[
https://issues.apache.org/jira/browse/ZOOKEEPER-1702?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13653397#comment-13653397
]
Chris Nauroth commented on ZOOKEEPER-1702:
------------------------------------------
Thanks, Patrick. I hadn't considered the C client until now. This is more of
a general socket programming issue than a Java-specific issue, so in theory the
bug could be there too.
>From a very quick glance at the C code, I couldn't find the bug there. I'm
>basing that statement on the fact that {{zookeeper_interest}} only turns on
>write interest while connecting or after fully connected:
{code}
/* we are interested in a write if we are connected and have something
* to send, or we are waiting for a connect to finish. */
if ((zh->to_send.head && (zh->state == ZOO_CONNECTED_STATE))
|| zh->state == ZOO_CONNECTING_STATE) {
*interest |= ZOOKEEPER_WRITE;
}
{code}
And it only enters {{ZOO_CONNECTED_STATE}} after successful negotation of
connection and checking session inside {{check_events}}:
{code}
oldid = zh->client_id.client_id;
newid = zh->primer_storage.sessionId;
if (oldid != 0 && oldid != newid) {
zh->state = ZOO_EXPIRED_SESSION_STATE;
errno = ESTALE;
return handle_socket_error_msg(zh,__LINE__,ZSESSIONEXPIRED,
"sessionId=%#llx has expired.",oldid);
} else {
zh->recv_timeout = zh->primer_storage.timeOut;
zh->client_id.client_id = newid;
memcpy(zh->client_id.passwd, &zh->primer_storage.passwd,
sizeof(zh->client_id.passwd));
zh->state = ZOO_CONNECTED_STATE;
{code}
Therefore, I don't think the C client has the bug. At least that's my very
naive take on it after a whole 10 minutes reading the code. :-)
On the Java side, the logic was different in that it would immediately turn on
both read and write interest in {{ClientCnxn#SendThread#primeConnection}}, and
leave write interest on until the outgoing queue got drained.
> ZooKeeper client may write operation packets before receiving successful
> response to connection request, can cause TCP RST
> --------------------------------------------------------------------------------------------------------------------------
>
> Key: ZOOKEEPER-1702
> URL: https://issues.apache.org/jira/browse/ZOOKEEPER-1702
> Project: ZooKeeper
> Issue Type: Bug
> Components: java client
> Affects Versions: 3.4.2
> Reporter: Chris Nauroth
> Assignee: Chris Nauroth
> Fix For: 3.5.0, 3.4.6
>
> Attachments: ZOOKEEPER-1702.1.patch
>
>
> The problem occurs when a connection attempt is pending and there are
> multiple outbound packets in the queue for other operations. In
> {{ClientCnxnSocketNIO#doIO}}, it is possible to receive notification that the
> socket is writable for the next operation packet before receiving
> notification that the socket is readable for the connection response from the
> server. If the server decides that the session is expired, then it responds
> by immediately closing the socket on its side. If the client has written
> packets after the server has closed its end of the socket, then the TCP stack
> may choose to abort the connection with an RST. When this happens, the
> client doesn't receive an orderly shutdown, and ultimately it fails to
> deliver a session expired event to the application.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira