-/* $OpenBSD: uipc_usrreq.c,v 1.191 2022/10/17 14:49:01 mvs Exp $ */
+/* $OpenBSD: uipc_usrreq.c,v 1.192 2022/11/13 16:01:32 mvs Exp $ */
/* $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $ */
/*
.pru_connect2 = uipc_connect2,
};
+const struct pr_usrreqs uipc_dgram_usrreqs = {
+ .pru_attach = uipc_attach,
+ .pru_detach = uipc_detach,
+ .pru_bind = uipc_bind,
+ .pru_listen = uipc_listen,
+ .pru_connect = uipc_connect,
+ .pru_disconnect = uipc_disconnect,
+ .pru_shutdown = uipc_dgram_shutdown,
+ .pru_send = uipc_dgram_send,
+ .pru_sense = uipc_sense,
+ .pru_sockaddr = uipc_sockaddr,
+ .pru_peeraddr = uipc_peeraddr,
+ .pru_connect2 = uipc_connect2,
+};
+
void
unp_init(void)
{
uipc_shutdown(struct socket *so)
{
struct unpcb *unp = sotounpcb(so);
+ struct socket *so2;
+
+ socantsendmore(so);
+
+ if ((so2 = unp_solock_peer(unp->unp_socket))){
+ socantrcvmore(so2);
+ sounlock(so2);
+ }
+
+ return (0);
+}
+int
+uipc_dgram_shutdown(struct socket *so)
+{
socantsendmore(so);
- unp_shutdown(unp);
return (0);
}
{
struct socket *so2;
- switch (so->so_type) {
- case SOCK_DGRAM:
- panic("uipc 1");
- /*NOTREACHED*/
-
- case SOCK_STREAM:
- case SOCK_SEQPACKET:
- if ((so2 = unp_solock_peer(so)) == NULL)
- break;
- /*
- * Adjust backpressure on sender
- * and wakeup any waiting to write.
- */
- so2->so_snd.sb_mbcnt = so->so_rcv.sb_mbcnt;
- so2->so_snd.sb_cc = so->so_rcv.sb_cc;
- sowwakeup(so2);
- sounlock(so2);
- break;
-
- default:
- panic("uipc 2");
- }
+ if ((so2 = unp_solock_peer(so)) == NULL)
+ return;
+ /*
+ * Adjust backpressure on sender
+ * and wakeup any waiting to write.
+ */
+ so2->so_snd.sb_mbcnt = so->so_rcv.sb_mbcnt;
+ so2->so_snd.sb_cc = so->so_rcv.sb_cc;
+ sowwakeup(so2);
+ sounlock(so2);
}
int
uipc_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
struct mbuf *control)
{
- struct unpcb *unp = sotounpcb(so);
struct socket *so2;
int error = 0;
goto out;
}
- switch (so->so_type) {
- case SOCK_DGRAM: {
- const struct sockaddr *from;
+ if (so->so_state & SS_CANTSENDMORE) {
+ error = EPIPE;
+ goto dispose;
+ }
+ if ((so2 = unp_solock_peer(so)) == NULL) {
+ error = ENOTCONN;
+ goto dispose;
+ }
- if (nam) {
- if (unp->unp_conn) {
- error = EISCONN;
- break;
- }
- error = unp_connect(so, nam, curproc);
- if (error)
- break;
+ /*
+ * Send to paired receive port, and then raise
+ * send buffer counts to maintain backpressure.
+ * Wake up readers.
+ */
+ if (control) {
+ if (sbappendcontrol(so2, &so2->so_rcv, m, control)) {
+ control = NULL;
+ } else {
+ sounlock(so2);
+ error = ENOBUFS;
+ goto dispose;
}
+ } else if (so->so_type == SOCK_SEQPACKET)
+ sbappendrecord(so2, &so2->so_rcv, m);
+ else
+ sbappend(so2, &so2->so_rcv, m);
+ so->so_snd.sb_mbcnt = so2->so_rcv.sb_mbcnt;
+ so->so_snd.sb_cc = so2->so_rcv.sb_cc;
+ if (so2->so_rcv.sb_cc > 0)
+ sorwakeup(so2);
- if ((so2 = unp_solock_peer(so)) == NULL) {
- if (nam != NULL)
- error = ECONNREFUSED;
- else
- error = ENOTCONN;
- break;
- }
+ sounlock(so2);
+ m = NULL;
- if (unp->unp_addr)
- from = mtod(unp->unp_addr, struct sockaddr *);
- else
- from = &sun_noname;
- if (sbappendaddr(so2, &so2->so_rcv, from, m, control)) {
- sorwakeup(so2);
- m = NULL;
- control = NULL;
- } else
- error = ENOBUFS;
+dispose:
+ /* we need to undo unp_internalize in case of errors */
+ if (control && error)
+ unp_dispose(control);
- if (so2 != so)
- sounlock(so2);
+out:
+ m_freem(control);
+ m_freem(m);
- if (nam)
- unp_disconnect(unp);
- break;
+ return (error);
+}
+
+int
+uipc_dgram_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+ struct mbuf *control)
+{
+ struct unpcb *unp = sotounpcb(so);
+ struct socket *so2;
+ const struct sockaddr *from;
+ int error = 0;
+
+ if (control) {
+ sounlock(so);
+ error = unp_internalize(control, curproc);
+ solock(so);
+ if (error)
+ goto out;
}
- case SOCK_STREAM:
- case SOCK_SEQPACKET:
- if (so->so_state & SS_CANTSENDMORE) {
- error = EPIPE;
- break;
- }
- if ((so2 = unp_solock_peer(so)) == NULL) {
- error = ENOTCONN;
- break;
+ if (nam) {
+ if (unp->unp_conn) {
+ error = EISCONN;
+ goto dispose;
}
+ error = unp_connect(so, nam, curproc);
+ if (error)
+ goto dispose;
+ }
- /*
- * Send to paired receive port, and then raise
- * send buffer counts to maintain backpressure.
- * Wake up readers.
- */
- if (control) {
- if (sbappendcontrol(so2, &so2->so_rcv, m, control)) {
- control = NULL;
- } else {
- sounlock(so2);
- error = ENOBUFS;
- break;
- }
- } else if (so->so_type == SOCK_SEQPACKET)
- sbappendrecord(so2, &so2->so_rcv, m);
+ if ((so2 = unp_solock_peer(so)) == NULL) {
+ if (nam != NULL)
+ error = ECONNREFUSED;
else
- sbappend(so2, &so2->so_rcv, m);
- so->so_snd.sb_mbcnt = so2->so_rcv.sb_mbcnt;
- so->so_snd.sb_cc = so2->so_rcv.sb_cc;
- if (so2->so_rcv.sb_cc > 0)
- sorwakeup(so2);
+ error = ENOTCONN;
+ goto dispose;
+ }
- sounlock(so2);
+ if (unp->unp_addr)
+ from = mtod(unp->unp_addr, struct sockaddr *);
+ else
+ from = &sun_noname;
+ if (sbappendaddr(so2, &so2->so_rcv, from, m, control)) {
+ sorwakeup(so2);
m = NULL;
- break;
+ control = NULL;
+ } else
+ error = ENOBUFS;
- default:
- panic("uipc 4");
- }
+ if (so2 != so)
+ sounlock(so2);
+ if (nam)
+ unp_disconnect(unp);
+
+dispose:
/* we need to undo unp_internalize in case of errors */
if (control && error)
unp_dispose(control);
sounlock(so2);
}
-void
-unp_shutdown(struct unpcb *unp)
-{
- struct socket *so2;
-
- switch (unp->unp_socket->so_type) {
- case SOCK_STREAM:
- case SOCK_SEQPACKET:
- if ((so2 = unp_solock_peer(unp->unp_socket)) == NULL)
- break;
-
- socantrcvmore(so2);
- sounlock(so2);
-
- break;
- default:
- break;
- }
-}
-
static struct unpcb *
fptounp(struct file *fp)
{
-/* $OpenBSD: unpcb.h,v 1.43 2022/10/17 14:49:02 mvs Exp $ */
+/* $OpenBSD: unpcb.h,v 1.44 2022/11/13 16:01:32 mvs Exp $ */
/* $NetBSD: unpcb.h,v 1.6 1994/06/29 06:46:08 cgd Exp $ */
/*
};
extern const struct pr_usrreqs uipc_usrreqs;
+extern const struct pr_usrreqs uipc_dgram_usrreqs;
int uipc_attach(struct socket *, int, int);
int uipc_detach(struct socket *);
int uipc_accept(struct socket *, struct mbuf *);
int uipc_disconnect(struct socket *);
int uipc_shutdown(struct socket *);
+int uipc_dgram_shutdown(struct socket *);
void uipc_rcvd(struct socket *);
int uipc_send(struct socket *, struct mbuf *, struct mbuf *,
struct mbuf *);
+int uipc_dgram_send(struct socket *, struct mbuf *, struct mbuf *,
+ struct mbuf *);
void uipc_abort(struct socket *);
int uipc_sense(struct socket *, struct stat *);
int uipc_sockaddr(struct socket *, struct mbuf *);
void unp_detach(struct unpcb *);
void unp_disconnect(struct unpcb *);
void unp_gc(void *);
-void unp_shutdown(struct unpcb *);
int unp_externalize(struct mbuf *, socklen_t, int);
int unp_internalize(struct mbuf *, struct proc *);
void unp_dispose(struct mbuf *);