diff options
author | Anders Persson <Anders.Persson@Sun.COM> | 2009-10-21 19:52:57 -0700 |
---|---|---|
committer | Anders Persson <Anders.Persson@Sun.COM> | 2009-10-21 19:52:57 -0700 |
commit | dc7c11716d554aadaff1e4f6a09a5f3d222f421d (patch) | |
tree | 89994738c88ee43d66b9fab4bd4a4d1fd75ebe15 /usr/src | |
parent | 491f61a1e1c1fc54a47bbcf53dbbbe1293b93b27 (diff) | |
download | illumos-gate-dc7c11716d554aadaff1e4f6a09a5f3d222f421d.tar.gz |
6867122 writes on tcp sockets can return ENOTCONN after receiving a RST
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/inet/tcp.h | 8 | ||||
-rw-r--r-- | usr/src/uts/common/inet/tcp/tcp.c | 26 |
2 files changed, 20 insertions, 14 deletions
diff --git a/usr/src/uts/common/inet/tcp.h b/usr/src/uts/common/inet/tcp.h index ae7f471809..8442c4f384 100644 --- a/usr/src/uts/common/inet/tcp.h +++ b/usr/src/uts/common/inet/tcp.h @@ -597,11 +597,9 @@ typedef struct tcp_s { 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; diff --git a/usr/src/uts/common/inet/tcp/tcp.c b/usr/src/uts/common/inet/tcp/tcp.c index 96a762f1e9..a6f3ee8331 100644 --- a/usr/src/uts/common/inet/tcp/tcp.c +++ b/usr/src/uts/common/inet/tcp/tcp.c @@ -5529,7 +5529,7 @@ tcp_conn_request(void *arg, mblk_t *mp, void *arg2) * 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 @@ tcp_post_ip_bind(tcp_t *tcp, mblk_t *mp, int error, cred_t *cr, pid_t pid) } 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 @@ tcp_do_connect(conn_t *connp, const struct sockaddr *sa, socklen_t len, */ /* 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 @@ tcp_sendmsg(sock_lower_handle_t proto_handle, mblk_t *mp, struct nmsghdr *msg, 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); |