summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/inet/tcp/tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/inet/tcp/tcp.c')
-rw-r--r--usr/src/uts/common/inet/tcp/tcp.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/usr/src/uts/common/inet/tcp/tcp.c b/usr/src/uts/common/inet/tcp/tcp.c
index 356cbd279c..23eaaf43cf 100644
--- a/usr/src/uts/common/inet/tcp/tcp.c
+++ b/usr/src/uts/common/inet/tcp/tcp.c
@@ -12914,6 +12914,12 @@ tcp_rput_data(void *arg, mblk_t *mp, void *arg2)
* the connection has been accept()ed since it can't
* buffer OOB data. Discard segment if this happens.
*
+ * We can't just rely on a non-null tcp_listener to indicate
+ * that the accept() has completed since unlinking of the
+ * eager and completion of the accept are not atomic.
+ * tcp_detached, when it is not set (B_FALSE) indicates
+ * that the accept() has completed.
+ *
* Nor can it reassemble urgent pointers, so discard
* if it's not the next segment expected.
*
@@ -12922,7 +12928,7 @@ tcp_rput_data(void *arg, mblk_t *mp, void *arg2)
* data, and new data all are in the same mblk.
*/
ASSERT(mp != NULL);
- if (tcp->tcp_listener || !pullupmsg(mp, -1)) {
+ if (tcp->tcp_detached || !pullupmsg(mp, -1)) {
freemsg(mp);
return;
}
@@ -18769,6 +18775,7 @@ tcp_send_find_ire(tcp_t *tcp, ipaddr_t *dst, ire_t **irep)
if (CONN_CACHE_IRE(connp)) {
rw_enter(&ire->ire_bucket->irb_lock, RW_READER);
if (!(ire->ire_marks & IRE_MARK_CONDEMNED)) {
+ TCP_CHECK_IREINFO(tcp, ire);
connp->conn_ire_cache = ire;
cached = B_TRUE;
}