[ 
https://issues.apache.org/jira/browse/ZOOKEEPER-3420?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Suhas Dantkale updated ZOOKEEPER-3420:
--------------------------------------
    Description: 
With newer ZK C Client (3.5.*) and older ZK server(3.4.*), recv_buffer() could 
potentially return 0 continuously on non-blocking socket.

Following in the recv_buffer() snippet:-
Here, should  the check be:
if (buff == &zh->primer_buffer && buff->curr_offset + rc == buff->len + 
sizeof(buff->len)  - 1) ++rc;
instead of
if (buff == &zh->primer_buffer && rc == buff->len - 1) ++rc;

snippet :-

  if (buff->buffer) {
        /* want off to now represent the offset into the buffer */
        off -= sizeof(buff->len);

        rc = recv(zh->fd, buff->buffer+off, buff->len-off, 0);

        /* dirty hack to make new client work against old server
         * old server sends 40 bytes to finish connection handshake,
         * while we're expecting 41 (1 byte for read-only mode data) */
      if (buff == &zh->primer_buffer && rc == buff->len - 1) ++rc;  <====== 
Problem Line(?)

        switch(rc) {
        case 0:
            errno = EHOSTDOWN;
        case -1:
#ifdef _WIN32
            if (WSAGetLastError() == WSAEWOULDBLOCK) {
#else
            if (errno == EAGAIN) {
#endif
                break;
            }
            return -1;
        default:
            buff->curr_offset += rc;
        }
    }
    return buff->curr_offset == buff->len + sizeof(buff->len);


Probably the given code assumes that recv() operation will read in one go.
But on non-blocking socket, that assumption doesn't hold true.


  was:
With newer ZK C Client (3.5.*) and older ZK server(3.4.*), recv_buffer() could 
potentially return 0 continuously on non-blocking socket.

Following in the recv_buffer() snippet:-
Here, should  the check be:
if (buff == &zh->primer_buffer && buff->curr_offset + rc == buff->len + 
sizeof(buff->len)  - 1) ++rc;
instead of
if (buff == &zh->primer_buffer && rc == buff->len - 1) ++rc;

  if (buff->buffer) {
        /* want off to now represent the offset into the buffer */
        off -= sizeof(buff->len);

        rc = recv(zh->fd, buff->buffer+off, buff->len-off, 0);

        /* dirty hack to make new client work against old server
         * old server sends 40 bytes to finish connection handshake,
         * while we're expecting 41 (1 byte for read-only mode data) */
      if (buff == &zh->primer_buffer && rc == buff->len - 1) ++rc;

        switch(rc) {
        case 0:
            errno = EHOSTDOWN;
        case -1:
#ifdef _WIN32
            if (WSAGetLastError() == WSAEWOULDBLOCK) {
#else
            if (errno == EAGAIN) {
#endif
                break;
            }
            return -1;
        default:
            buff->curr_offset += rc;
        }
    }
    return buff->curr_offset == buff->len + sizeof(buff->len);


Probably the given code assumes that recv() operation will read in one go.
But on non-blocking socket, that assumption doesn't hold true.



> With newer ZK C Client and older ZK server, recv_buffer() could potentially 
> return 0 continuously on non-blocking socket
> ------------------------------------------------------------------------------------------------------------------------
>
>                 Key: ZOOKEEPER-3420
>                 URL: https://issues.apache.org/jira/browse/ZOOKEEPER-3420
>             Project: ZooKeeper
>          Issue Type: Bug
>          Components: c client
>    Affects Versions: 3.5.3
>            Reporter: Suhas Dantkale
>            Priority: Major
>
> With newer ZK C Client (3.5.*) and older ZK server(3.4.*), recv_buffer() 
> could potentially return 0 continuously on non-blocking socket.
> Following in the recv_buffer() snippet:-
> Here, should  the check be:
> if (buff == &zh->primer_buffer && buff->curr_offset + rc == buff->len + 
> sizeof(buff->len)  - 1) ++rc;
> instead of
> if (buff == &zh->primer_buffer && rc == buff->len - 1) ++rc;
> snippet :-
>   if (buff->buffer) {
>         /* want off to now represent the offset into the buffer */
>         off -= sizeof(buff->len);
>         rc = recv(zh->fd, buff->buffer+off, buff->len-off, 0);
>         /* dirty hack to make new client work against old server
>          * old server sends 40 bytes to finish connection handshake,
>          * while we're expecting 41 (1 byte for read-only mode data) */
>       if (buff == &zh->primer_buffer && rc == buff->len - 1) ++rc;  <====== 
> Problem Line(?)
>         switch(rc) {
>         case 0:
>             errno = EHOSTDOWN;
>         case -1:
> #ifdef _WIN32
>             if (WSAGetLastError() == WSAEWOULDBLOCK) {
> #else
>             if (errno == EAGAIN) {
> #endif
>                 break;
>             }
>             return -1;
>         default:
>             buff->curr_offset += rc;
>         }
>     }
>     return buff->curr_offset == buff->len + sizeof(buff->len);
> Probably the given code assumes that recv() operation will read in one go.
> But on non-blocking socket, that assumption doesn't hold true.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to