Page MenuHomeFreeBSD

D31976.diff
No OneTemporary

D31976.diff

diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -2847,13 +2847,14 @@
int
soshutdown(struct socket *so, int how)
{
- struct protosw *pr = so->so_proto;
+ struct protosw *pr;
int error, soerror_enotconn;
if (!(how == SHUT_RD || how == SHUT_WR || how == SHUT_RDWR))
return (EINVAL);
soerror_enotconn = 0;
+ SOCK_LOCK(so);
if ((so->so_state &
(SS_ISCONNECTED | SS_ISCONNECTING | SS_ISDISCONNECTING)) == 0) {
/*
@@ -2865,21 +2866,26 @@
* both backward-compatibility and POSIX requirements by forcing
* ENOTCONN but still asking protocol to perform pru_shutdown().
*/
- if (so->so_type != SOCK_DGRAM && !SOLISTENING(so))
+ if (so->so_type != SOCK_DGRAM && !SOLISTENING(so)) {
+ SOCK_UNLOCK(so);
return (ENOTCONN);
+ }
soerror_enotconn = 1;
}
if (SOLISTENING(so)) {
if (how != SHUT_WR) {
- SOLISTEN_LOCK(so);
so->so_error = ECONNABORTED;
solisten_wakeup(so); /* unlocks so */
+ } else {
+ SOCK_UNLOCK(so);
}
goto done;
}
+ SOCK_UNLOCK(so);
CURVNET_SET(so->so_vnet);
+ pr = so->so_proto;
if (pr->pr_usrreqs->pru_flush != NULL)
(*pr->pr_usrreqs->pru_flush)(so, how);
if (how != SHUT_WR)
@@ -2900,20 +2906,21 @@
void
sorflush(struct socket *so)
{
- struct sockbuf *sb = &so->so_rcv;
- struct protosw *pr = so->so_proto;
struct socket aso;
+ struct protosw *pr;
int error;
VNET_SO_ASSERT(so);
/*
* In order to avoid calling dom_dispose with the socket buffer mutex
- * held, and in order to generally avoid holding the lock for a long
- * time, we make a copy of the socket buffer and clear the original
- * (except locks, state). The new socket buffer copy won't have
- * initialized locks so we can only call routines that won't use or
- * assert those locks.
+ * held, we make a partial copy of the socket buffer and clear the
+ * original. The new socket buffer copy won't have initialized locks so
+ * we can only call routines that won't use or assert those locks.
+ * Ideally calling socantrcvmore() would prevent data from being added
+ * to the buffer, but currently it merely prevents buffered data from
+ * being read by userspace. We make this effort to free buffered data
+ * nonetheless.
*
* Dislodge threads currently blocked in receive and wait to acquire
* a lock against other simultaneous readers before clearing the
@@ -2921,28 +2928,31 @@
* despite any existing socket disposition on interruptable waiting.
*/
socantrcvmore(so);
+
error = SOCK_IO_RECV_LOCK(so, SBL_WAIT | SBL_NOINTR);
- KASSERT(error == 0, ("%s: cannot lock sock %p recv buffer",
- __func__, so));
+ if (error != 0) {
+ KASSERT(SOLISTENING(so),
+ ("%s: soiolock(%p) failed", __func__, so));
+ return;
+ }
- /*
- * Invalidate/clear most of the sockbuf structure, but leave selinfo
- * and mutex data unchanged.
- */
- SOCKBUF_LOCK(sb);
+ SOCK_RECVBUF_LOCK(so);
bzero(&aso, sizeof(aso));
aso.so_pcb = so->so_pcb;
- bcopy(&sb->sb_startzero, &aso.so_rcv.sb_startzero,
- sizeof(*sb) - offsetof(struct sockbuf, sb_startzero));
- bzero(&sb->sb_startzero,
- sizeof(*sb) - offsetof(struct sockbuf, sb_startzero));
- SOCKBUF_UNLOCK(sb);
+ bcopy(&so->so_rcv.sb_startzero, &aso.so_rcv.sb_startzero,
+ offsetof(struct sockbuf, sb_endzero) -
+ offsetof(struct sockbuf, sb_startzero));
+ bzero(&so->so_rcv.sb_startzero,
+ offsetof(struct sockbuf, sb_endzero) -
+ offsetof(struct sockbuf, sb_startzero));
+ SOCK_RECVBUF_UNLOCK(so);
SOCK_IO_RECV_UNLOCK(so);
/*
* Dispose of special rights and flush the copied socket. Don't call
* any unsafe routines (that rely on locks being initialized) on aso.
*/
+ pr = so->so_proto;
if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose != NULL)
(*pr->pr_domain->dom_dispose)(&aso);
sbrelease_internal(&aso.so_rcv, so);
diff --git a/sys/sys/sockbuf.h b/sys/sys/sockbuf.h
--- a/sys/sys/sockbuf.h
+++ b/sys/sys/sockbuf.h
@@ -104,12 +104,13 @@
u_int sb_tlsdcc; /* (a) TLS characters being decrypted */
int sb_lowat; /* (a) low water mark */
sbintime_t sb_timeo; /* (a) timeout for read/write */
- uint64_t sb_tls_seqno; /* (a) TLS seqno */
- struct ktls_session *sb_tls_info; /* (a + b) TLS state */
struct mbuf *sb_mtls; /* (a) TLS mbuf chain */
struct mbuf *sb_mtlstail; /* (a) last mbuf in TLS chain */
int (*sb_upcall)(struct socket *, void *, int); /* (a) */
void *sb_upcallarg; /* (a) */
+#define sb_endzero sb_tls_seqno
+ uint64_t sb_tls_seqno; /* (a) TLS seqno */
+ struct ktls_session *sb_tls_info; /* (a + b) TLS state */
TAILQ_HEAD(, kaiocb) sb_aiojobq; /* (a) pending AIO ops */
struct task sb_aiotask; /* AIO task */
};

File Metadata

Mime Type
text/plain
Expires
Thu, Apr 16, 9:08 AM (9 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31582179
Default Alt Text
D31976.diff (4 KB)

Event Timeline