changeset 13087:71556dfac9dc

6966638 shutdown() sometimes appears to shutdown the wrong channel in a full-duplex socket.
author George Shepherd <George.Shepherd@Sun.COM>
date Wed, 11 Aug 2010 12:59:10 -0700
parents 787bf65954d0
children e0735b974926
files usr/src/uts/common/fs/sockfs/socktpi.c
diffstat 1 files changed, 11 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/fs/sockfs/socktpi.c	Wed Aug 11 13:39:17 2010 -0600
+++ b/usr/src/uts/common/fs/sockfs/socktpi.c	Wed Aug 11 12:59:10 2010 -0700
@@ -2076,13 +2076,20 @@
 		eprintsoline(so, error);
 		goto disconnect_vp;
 	}
+	mutex_exit(&so->so_lock);
 	/*
 	 * If there is a sin/sin6 appended onto the T_OK_ACK use
 	 * that to set the local address. If this is not present
 	 * then we zero out the address and don't set the
 	 * sti_laddr_valid bit. For AF_UNIX endpoints we copy over
 	 * the pathname from the listening socket.
+	 * In the case where this is TCP or an AF_UNIX socket the
+	 * client side may have queued data or a T_ORDREL in the
+	 * transport. Having now sent the T_CONN_RES we may receive
+	 * those queued messages at any time. Hold the acceptor
+	 * so_lock until its state and laddr are finalized.
 	 */
+	mutex_enter(&nso->so_lock);
 	sinlen = (nso->so_family == AF_INET) ? sizeof (sin_t) : sizeof (sin6_t);
 	if ((nso->so_family == AF_INET) || (nso->so_family == AF_INET6) &&
 	    MBLKL(ack_mp) == (sizeof (struct T_ok_ack) + sinlen)) {
@@ -2103,13 +2110,15 @@
 		bzero(nsti->sti_laddr_sa, nsti->sti_addr_size);
 		nsti->sti_laddr_sa->sa_family = nso->so_family;
 	}
+	nso->so_state |= SS_ISCONNECTED;
+	mutex_exit(&nso->so_lock);
+
 	freemsg(ack_mp);
 
+	mutex_enter(&so->so_lock);
 	so_unlock_single(so, SOLOCKED);
 	mutex_exit(&so->so_lock);
 
-	nso->so_state |= SS_ISCONNECTED;
-
 	/*
 	 * Pass out new socket.
 	 */