[ 
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

Reply via email to