Skip to content

Commit f732adc

Browse files
authored
io BUGFIX do not fail when there is data left to read (#229)
When using the UNIX transport and depending on the timing between the server and client, the client may read the final reply to the <close-session> rpc *after* the server has closed the socket. When that occurs, poll() returns POLLHUP in revents meaning the server closed the socket which causes the following error on the client: ERR: Session 1: communication channel unexpectedly closed. ERR: Session 1: failed to receive a reply to <close-session>. When POLLHUP is returned in revents, make sure POLLIN is not present as well (if it is, it means that there is some data left to be read in the socket buffer). Link: https://www.greenend.org.uk/rjk/tech/poll.html Signed-off-by: Robin Jarry <robin.jarry@6wind.com>
1 parent f8512cc commit f732adc

1 file changed

Lines changed: 8 additions & 6 deletions

File tree

src/io.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -605,18 +605,20 @@ nc_read_poll(struct nc_session *session, int io_timeout)
605605
return -1;
606606
} else { /* status > 0 */
607607
/* in case of standard (non-libssh) poll, there still can be an error */
608-
if (fds.revents & POLLHUP) {
609-
ERR("Session %u: communication channel unexpectedly closed.", session->id);
610-
session->status = NC_STATUS_INVALID;
611-
session->term_reason = NC_SESSION_TERM_DROPPED;
612-
return -1;
613-
}
614608
if (fds.revents & POLLERR) {
615609
ERR("Session %u: communication channel error.", session->id);
616610
session->status = NC_STATUS_INVALID;
617611
session->term_reason = NC_SESSION_TERM_OTHER;
618612
return -1;
619613
}
614+
/* Some poll() implementations may return POLLHUP|POLLIN when the other
615+
* side has closed but there is data left to read in the buffer. */
616+
if ((fds.revents & POLLHUP) && !(fds.revents & POLLIN)) {
617+
ERR("Session %u: communication channel unexpectedly closed.", session->id);
618+
session->status = NC_STATUS_INVALID;
619+
session->term_reason = NC_SESSION_TERM_DROPPED;
620+
return -1;
621+
}
620622
}
621623

622624
return ret;

0 commit comments

Comments
 (0)