Mercurial > illumos > illumos-gate
changeset 10832:1770c9c8b380
6867122 writes on tcp sockets can return ENOTCONN after receiving a RST
author | Anders Persson <Anders.Persson@Sun.COM> |
---|---|
date | Wed, 21 Oct 2009 19:52:57 -0700 |
parents | e65585ea170c |
children | 148e8c056d10 |
files | usr/src/uts/common/inet/tcp.h usr/src/uts/common/inet/tcp/tcp.c |
diffstat | 2 files changed, 20 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/inet/tcp.h Wed Oct 21 16:35:06 2009 -0700 +++ b/usr/src/uts/common/inet/tcp.h Wed Oct 21 19:52:57 2009 -0700 @@ -597,11 +597,9 @@ uint32_t tcp_snxt_shrunk; /* - * The socket generation number is bumped when an outgoing connection - * attempts is made, and it sent up to the socket when the - * connection was successfully established, or an error occured. The - * generation is used to ensure that the socket does not miss the - * asynchronous notification. + * Socket generation number which is bumped when a connection attempt + * is initiated. Its main purpose is to ensure that the socket does not + * miss the asynchronous connected/disconnected notification. */ sock_connid_t tcp_connid;
--- a/usr/src/uts/common/inet/tcp/tcp.c Wed Oct 21 16:35:06 2009 -0700 +++ b/usr/src/uts/common/inet/tcp/tcp.c Wed Oct 21 19:52:57 2009 -0700 @@ -5529,7 +5529,7 @@ * Also check that source is not a multicast or broadcast address. */ eager->tcp_state = TCPS_SYN_RCVD; - + SOCK_CONNID_BUMP(eager->tcp_connid); /* * There should be no ire in the mp as we are being called after @@ -25858,6 +25858,14 @@ } else { mblk_setcred(syn_mp, cr, pid); } + + /* + * We must bump the generation before sending the syn + * to ensure that we use the right generation in case + * this thread issues a "connected" up call. + */ + SOCK_CONNID_BUMP(tcp->tcp_connid); + tcp_send_data(tcp, tcp->tcp_wq, syn_mp); } after_syn_sent: @@ -26385,13 +26393,6 @@ */ /* FALLTHRU */ case TCPS_BOUND: - /* - * We must bump the generation before the operation start. - * This is done to ensure that any upcall made later on sends - * up the right generation to the socket. - */ - SOCK_CONNID_BUMP(tcp->tcp_connid); - if (tcp->tcp_family == AF_INET6) { if (!IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { return (tcp_connect_ipv6(tcp, @@ -26635,7 +26636,14 @@ tcpstate = tcp->tcp_state; if (tcpstate < TCPS_ESTABLISHED) { freemsg(mp); - return (ENOTCONN); + /* + * We return ENOTCONN if the endpoint is trying to + * connect or has never been connected, and EPIPE if it + * has been disconnected. The connection id helps us + * distinguish between the last two cases. + */ + return ((tcpstate == TCPS_SYN_SENT) ? ENOTCONN : + ((tcp->tcp_connid > 0) ? EPIPE : ENOTCONN)); } else if (tcpstate > TCPS_CLOSE_WAIT) { freemsg(mp); return (EPIPE);