-/* $OpenBSD: uipc_socket.c,v 1.317 2024/02/05 20:21:38 mvs Exp $ */
+/* $OpenBSD: uipc_socket.c,v 1.318 2024/02/11 18:14:26 mvs Exp $ */
/* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */
/*
TAILQ_INIT(&so->so_q0);
TAILQ_INIT(&so->so_q);
+ switch (dp->dom_family) {
+ case AF_INET:
+ case AF_INET6:
+ switch (dp->dom_protosw->pr_type) {
+ case SOCK_DGRAM:
+ case SOCK_RAW:
+ so->so_rcv.sb_flags |= SB_MTXLOCK;
+ break;
+ }
+ break;
+ }
+
return (so);
}
sounlock_shared(so);
return (error);
}
- pru_lock(so);
+ sb_mtx_lock(&so->so_rcv);
m = so->so_rcv.sb_mb;
#ifdef SOCKET_SPLICE
SBLASTRECORDCHK(&so->so_rcv, "soreceive sbwait 1");
SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 1");
sbunlock(so, &so->so_rcv);
- pru_unlock(so);
+ sb_mtx_unlock(&so->so_rcv);
error = sbwait(so, &so->so_rcv);
if (error) {
sounlock_shared(so);
sbsync(&so->so_rcv, nextrecord);
if (controlp) {
if (pr->pr_domain->dom_externalize) {
- pru_unlock(so);
+ sb_mtx_unlock(&so->so_rcv);
sounlock_shared(so);
error =
(*pr->pr_domain->dom_externalize)
(cm, controllen, flags);
solock_shared(so);
- pru_lock(so);
+ sb_mtx_lock(&so->so_rcv);
}
*controlp = cm;
} else {
SBLASTRECORDCHK(&so->so_rcv, "soreceive uiomove");
SBLASTMBUFCHK(&so->so_rcv, "soreceive uiomove");
resid = uio->uio_resid;
- pru_unlock(so);
+ sb_mtx_unlock(&so->so_rcv);
sounlock_shared(so);
uio_error = uiomove(mtod(m, caddr_t) + moff, len, uio);
solock_shared(so);
- pru_lock(so);
+ sb_mtx_lock(&so->so_rcv);
if (uio_error)
uio->uio_resid = resid - len;
} else
break;
SBLASTRECORDCHK(&so->so_rcv, "soreceive sbwait 2");
SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 2");
- pru_unlock(so);
+ sb_mtx_unlock(&so->so_rcv);
error = sbwait(so, &so->so_rcv);
if (error) {
sbunlock(so, &so->so_rcv);
sounlock_shared(so);
return (0);
}
- pru_lock(so);
+ sb_mtx_lock(&so->so_rcv);
if ((m = so->so_rcv.sb_mb) != NULL)
nextrecord = m->m_nextpkt;
}
(flags & MSG_EOR) == 0 &&
(so->so_rcv.sb_state & SS_CANTRCVMORE) == 0) {
sbunlock(so, &so->so_rcv);
- pru_unlock(so);
+ sb_mtx_unlock(&so->so_rcv);
goto restart;
}
*flagsp |= flags;
release:
sbunlock(so, &so->so_rcv);
- pru_unlock(so);
+ sb_mtx_unlock(&so->so_rcv);
sounlock_shared(so);
return (error);
}
-/* $OpenBSD: uipc_socket2.c,v 1.142 2024/02/05 20:21:38 mvs Exp $ */
+/* $OpenBSD: uipc_socket2.c,v 1.143 2024/02/11 18:14:26 mvs Exp $ */
/* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */
/*
return ret;
}
+void
+sbmtxassertlocked(struct socket *so, struct sockbuf *sb)
+{
+ if (sb->sb_flags & SB_MTXLOCK) {
+ if (splassert_ctl > 0 && mtx_owned(&sb->sb_mtx) == 0)
+ splassert_fail(0, RW_WRITE, __func__);
+ } else
+ soassertlocked(so);
+}
+
/*
* Wait for data to arrive at/drain from a socket buffer.
*/
struct mbuf *m, *n, *nlast;
int space = asa->sa_len;
- soassertlocked(so);
+ sbmtxassertlocked(so, sb);
if (m0 && (m0->m_flags & M_PKTHDR) == 0)
panic("sbappendaddr");
-/* $OpenBSD: ip_divert.c,v 1.93 2024/02/03 22:50:09 mvs Exp $ */
+/* $OpenBSD: ip_divert.c,v 1.94 2024/02/11 18:14:26 mvs Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
in_proto_cksum_out(m, NULL);
}
- mtx_enter(&inp->inp_mtx);
so = inp->inp_socket;
+ mtx_enter(&so->so_rcv.sb_mtx);
if (sbappendaddr(so, &so->so_rcv, sintosa(&sin), m, NULL) == 0) {
- mtx_leave(&inp->inp_mtx);
+ mtx_leave(&so->so_rcv.sb_mtx);
divstat_inc(divs_fullsock);
goto bad;
}
- mtx_leave(&inp->inp_mtx);
+ mtx_leave(&so->so_rcv.sb_mtx);
sorwakeup(so);
in_pcbunref(inp);
-/* $OpenBSD: ip_mroute.c,v 1.140 2023/12/06 09:27:17 bluhm Exp $ */
+/* $OpenBSD: ip_mroute.c,v 1.141 2024/02/11 18:14:26 mvs Exp $ */
/* $NetBSD: ip_mroute.c,v 1.85 2004/04/26 01:31:57 matt Exp $ */
/*
socket_send(struct socket *so, struct mbuf *mm, struct sockaddr_in *src)
{
if (so != NULL) {
- struct inpcb *inp = sotoinpcb(so);
int ret;
- mtx_enter(&inp->inp_mtx);
+ mtx_enter(&so->so_rcv.sb_mtx);
ret = sbappendaddr(so, &so->so_rcv, sintosa(src), mm, NULL);
- mtx_leave(&inp->inp_mtx);
+ mtx_leave(&so->so_rcv.sb_mtx);
if (ret != 0) {
sorwakeup(so);
-/* $OpenBSD: raw_ip.c,v 1.155 2024/02/03 22:50:09 mvs Exp $ */
+/* $OpenBSD: raw_ip.c,v 1.156 2024/02/11 18:14:26 mvs Exp $ */
/* $NetBSD: raw_ip.c,v 1.25 1996/02/18 18:58:33 christos Exp $ */
/*
else
n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
if (n != NULL) {
+ struct socket *so = inp->inp_socket;
int ret;
if (inp->inp_flags & INP_CONTROLOPTS ||
- inp->inp_socket->so_options & SO_TIMESTAMP)
+ so->so_options & SO_TIMESTAMP)
ip_savecontrol(inp, &opts, ip, n);
- mtx_enter(&inp->inp_mtx);
- ret = sbappendaddr(inp->inp_socket,
- &inp->inp_socket->so_rcv,
+ mtx_enter(&so->so_rcv.sb_mtx);
+ ret = sbappendaddr(so, &so->so_rcv,
sintosa(&ripsrc), n, opts);
- mtx_leave(&inp->inp_mtx);
+ mtx_leave(&so->so_rcv.sb_mtx);
if (ret == 0) {
/* should notify about lost packet */
m_freem(n);
m_freem(opts);
} else
- sorwakeup(inp->inp_socket);
+ sorwakeup(so);
}
in_pcbunref(inp);
}
-/* $OpenBSD: udp_usrreq.c,v 1.317 2024/02/03 22:50:09 mvs Exp $ */
+/* $OpenBSD: udp_usrreq.c,v 1.318 2024/02/11 18:14:26 mvs Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
/*
#endif
m_adj(m, hlen);
- mtx_enter(&inp->inp_mtx);
+ mtx_enter(&so->so_rcv.sb_mtx);
if (sbappendaddr(so, &so->so_rcv, srcaddr, m, opts) == 0) {
- mtx_leave(&inp->inp_mtx);
+ mtx_leave(&so->so_rcv.sb_mtx);
udpstat_inc(udps_fullsock);
m_freem(m);
m_freem(opts);
return;
}
- mtx_leave(&inp->inp_mtx);
+ mtx_leave(&so->so_rcv.sb_mtx);
sorwakeup(so);
}
-/* $OpenBSD: ip6_divert.c,v 1.93 2024/02/11 01:27:45 bluhm Exp $ */
+/* $OpenBSD: ip6_divert.c,v 1.94 2024/02/11 18:14:27 mvs Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
in6_proto_cksum_out(m, NULL);
}
- mtx_enter(&inp->inp_mtx);
so = inp->inp_socket;
+ mtx_enter(&so->so_rcv.sb_mtx);
if (sbappendaddr(so, &so->so_rcv, sin6tosa(&sin6), m, NULL) == 0) {
- mtx_leave(&inp->inp_mtx);
+ mtx_leave(&so->so_rcv.sb_mtx);
div6stat_inc(div6s_fullsock);
goto bad;
}
- mtx_leave(&inp->inp_mtx);
+ mtx_leave(&so->so_rcv.sb_mtx);
sorwakeup(so);
in_pcbunref(inp);
-/* $OpenBSD: ip6_mroute.c,v 1.139 2024/02/03 22:50:09 mvs Exp $ */
+/* $OpenBSD: ip6_mroute.c,v 1.140 2024/02/11 18:14:27 mvs Exp $ */
/* $NetBSD: ip6_mroute.c,v 1.59 2003/12/10 09:28:38 itojun Exp $ */
/* $KAME: ip6_mroute.c,v 1.45 2001/03/25 08:38:51 itojun Exp $ */
socket6_send(struct socket *so, struct mbuf *mm, struct sockaddr_in6 *src)
{
if (so != NULL) {
- struct inpcb *inp = sotoinpcb(so);
int ret;
- mtx_enter(&inp->inp_mtx);
+ mtx_enter(&so->so_rcv.sb_mtx);
ret = sbappendaddr(so, &so->so_rcv, sin6tosa(src), mm, NULL);
- if (ret != 0)
- sorwakeup(so);
- mtx_leave(&inp->inp_mtx);
+ mtx_leave(&so->so_rcv.sb_mtx);
- if (ret != 0)
+ if (ret != 0) {
+ sorwakeup(so);
return 0;
+ }
}
m_freem(mm);
return -1;
-/* $OpenBSD: raw_ip6.c,v 1.180 2024/02/03 22:50:09 mvs Exp $ */
+/* $OpenBSD: raw_ip6.c,v 1.181 2024/02/11 18:14:27 mvs Exp $ */
/* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */
/*
else
n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
if (n != NULL) {
+ struct socket *so = inp->inp_socket;
int ret;
if (inp->inp_flags & IN6P_CONTROLOPTS)
/* strip intermediate headers */
m_adj(n, *offp);
- mtx_enter(&inp->inp_mtx);
- ret = sbappendaddr(inp->inp_socket,
- &inp->inp_socket->so_rcv,
+ mtx_enter(&so->so_rcv.sb_mtx);
+ ret = sbappendaddr(so, &so->so_rcv,
sin6tosa(&rip6src), n, opts);
- mtx_leave(&inp->inp_mtx);
+ mtx_leave(&so->so_rcv.sb_mtx);
if (ret == 0) {
/* should notify about lost packet */
m_freem(opts);
rip6stat_inc(rip6s_fullsock);
} else
- sorwakeup(inp->inp_socket);
+ sorwakeup(so);
}
in_pcbunref(inp);
}
-/* $OpenBSD: socketvar.h,v 1.122 2024/02/03 22:50:09 mvs Exp $ */
+/* $OpenBSD: socketvar.h,v 1.123 2024/02/11 18:14:27 mvs Exp $ */
/* $NetBSD: socketvar.h,v 1.18 1996/02/09 18:25:38 christos Exp $ */
/*-
#define SB_ASYNC 0x10 /* ASYNC I/O, need signals */
#define SB_SPLICE 0x20 /* buffer is splice source or drain */
#define SB_NOINTR 0x40 /* operations not interruptible */
+#define SB_MTXLOCK 0x80 /* use sb_mtx for sockbuf protection */
void (*so_upcall)(struct socket *so, caddr_t arg, int waitf);
caddr_t so_upcallarg; /* Arg for above */
#define isspliced(so) ((so)->so_sp && (so)->so_sp->ssp_socket)
#define issplicedback(so) ((so)->so_sp && (so)->so_sp->ssp_soback)
+static inline void
+sb_mtx_lock(struct sockbuf *sb)
+{
+ if (sb->sb_flags & SB_MTXLOCK)
+ mtx_enter(&sb->sb_mtx);
+}
+
+static inline void
+sb_mtx_unlock(struct sockbuf *sb)
+{
+ if (sb->sb_flags & SB_MTXLOCK)
+ mtx_leave(&sb->sb_mtx);
+}
+
+void sbmtxassertlocked(struct socket *so, struct sockbuf *);
+
/*
* Do we need to notify the other side when I/O is possible?
*/