Subject: [ libssh2-Bugs-1918953 ] SSH disconnect detection

[ libssh2-Bugs-1918953 ] SSH disconnect detection

From: <>
Date: Tue, 28 Apr 2009 12:51:20 +0000

Bugs item #1918953, was opened at 2008-03-19 00:50
Message generated for change (Comment added) made by bagder
You can respond by visiting:

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: misc
Group: None
>Status: Closed
>Resolution: Wont Fix
Priority: 5
Private: No
Submitted By: Gary Miller (gmiller1018)
Assigned to: Nobody/Anonymous (nobody)
Summary: SSH disconnect detection

Initial Comment:
When using libssh2_poll with a INT max timeout and a socket disconnects there does not seem to be any response. I had expected the libssh2_poll to return with the appropriate status indication.

Status passed in as:

cur_fd-> = sess_flags[I].channel; // channel
  cur_fd->type = LIBSSH2_POLLFD_CHANNEL;
  cur_fd->events = LIBSSH2_POLLFD_POLLIN |
                   LIBSSH2_POLLFD_POLLERR |
                   LIBSSH2_POLLFD_POLLHUP |
                   LIBSSH2_POLLFD_POLLNVAL |
                   LIBSSH2_POLLFD_SESSION_CLOSED |

twait = INT_MAX; // wait forever for input or disconn.
Log_debug("Waiting in libssh2_poll");
nfound = libssh2_poll (ssh_fds, count, twait);
Log_debug("libssh2_poll returned");


there is only one socket open at the time and count is
set to 1 (in a select I would use 2). I am unsure if there is some behavior or other issue I need to consider to make this work. In past version of the library this worked but I had customized the code because of blocking behavior. This is pure latest release running on Fedora 7 using the RPM's. The connect and read and write appears to work correctly in general use but if the remote system server crashes the disconnect is not signaled so I never try to re-connect.

The socket have been set to non blocking by:
   0); // make nonblocking


>Comment By: Daniel Stenberg (bagder)
Date: 2009-04-28 14:51

libssh2_poll() is now considered deprecated so this bug will not be fixed.
You should simply not use this function anymore...


Comment By: Daniel Stenberg (bagder)
Date: 2008-09-29 15:48

Can you please post your suggested changes as a "regular" diff -u
output/patch ?


Comment By: Gary Miller (gmiller1018)
Date: 2008-03-22 00:34

Logged In: YES
Originator: YES

All comments were made by me ... I fogot to log in prior to adding them
... sorry


Comment By: Nobody/Anonymous (nobody)
Date: 2008-03-21 23:10

Logged In: NO

To work around the issue I modified the code in session.c at line 1544 to
[code libssh2 session.c]
   if (FD_ISSET(fds[i]>session->socket_fd, &rfds)) {
     int rc;

     fds[i].revents |= LIBSSH2_POLLFD_POLLIN; // force data flag ...(gwm)
     /* Spin session until no data available */
     while ((rc = libssh2_packet_read(fds[i]>session)) > 0);
// modified to get return code at exit (gwm)
     // check for socket closed ...
     if ( rc == PACKET_FAIL ) // new (gwm)
       fds[i].revents |= // new (gwm)
         LIBSSH2_POLLFD_CHANNEL_CLOSED | // new (gwm)
         LIBSSH2_POLLFD_SESSION_CLOSED; // new (gwm) .. the first
change might be all thats needed
[/code libssh2 (session.c)

In my code I use:
[my code]
if (ssh_fds[j].revents | (LIBSSH2_POLLFD_CHANNEL_CLOSED |
                           LIBSSH2_POLLFD_SESSION_CLOSED)) {
  length = 0; // signal no data so we will close socket
  Log_debug("SSH lost connection");
else {
  length = libssh2_channel_read (sess_flags[I].channel, // channel
                                 iptr[I], // buffer
                                 length); // max space in buffer
  Log_debug("Got %d SSH byte(s)", length);


The read if we ignore the close flags returns -37 ( libssh2's EAGAIN)

Of course this change is after I did the #undef HAVE_POLL so select()
would be
used and not poll().

At this point all appears to be working and the disconnect is being
returned to
my code so it can close the sockets and retry the connection and re-port

Of course my solution might not be an acceptable way of doing what you
so please do not react negatively.

I think the build environment needs to "undef" HAVE_POLL if select is
or split the functionality so one has precedence over the other. The
should set the events data to should a read has been done and the socket
flags need to be indicated as well (or one or the other, if we close the
heck with
the data.

I chose the PACKET_ERROR return code since that will be returned if the
recv in
libssh2_packet_read gets 0 bytes with no error (graceful socket exit).

Please let me know if there is a more general way to solve these issues so
I can
get them fixed in some upcoming release. I have been fixing the select()
/ poll()
issue for a while.


Comment By: Gary Miller (gmiller1018)
Date: 2008-03-21 03:59

Logged In: YES
Originator: YES

After further investigation there are a number of problems.
1.) If HAVE_POLL and HAVE_SELECT are both true then select will never be
used. I put a #undef HAVE_POLL to address this.
2.) To have the select return when the socket disconnect the select calls
need to have select(maxfds +1 ...)
3.) The loop reading data till complete does not set anything that
indicates the socket has closed because of the way it checks
    for a WOULD_BLOCK error (using the Windows terminology, I am using
4.) The code in the libssh2_poll for the select would not set the correct
status to indicate the socket was closed.


You can respond by visiting:

Register Now & Save for Velocity, the Web Performance & Operations
Conference from O'Reilly Media. Velocity features a full day of
expert-led, hands-on workshops and two days of sessions from industry
leaders in dedicated Performance & Operations tracks. Use code vel09scf
and Save an extra 15% before 5/3.
libssh2-devel mailing list
Received on 2009-04-28