[ 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)