Subject: Re: libssh2_session_free changes nonblock state of already unused fd

Re: libssh2_session_free changes nonblock state of already unused fd

From: Steven Ayre <>
Date: Fri, 28 Oct 2011 11:36:48 +0200

If you close the socket you should let libssh2 do that for you. Don't do it yourself.

There is a libssh2_disconnect function that will send the disconnect SSH message and close the socket. Instead of closing the socket yourself you should be calling that.

Net::SSH2 exposes that as the disconnect method. Use it!

Destroying the Net::SSH2 object by garbage collection is only for reclaiming the memory - not closing the connection, the disconnect method lets you do that earlier exactly when you want to.

Steve on iPhone

On 28 Oct 2011, at 10:11, Pavel Strashkin <> wrote:

> You're correct, but as i said we have the deal with a Perl, Python,
> whatever else that has GC which doesn't guarantee anything to you. An
> object can be destroyed at an time. In this world you should you take
> care of it too (in case if it happens). My point here (no hacks, no
> workarounds) is that you shouldn't change IO from blocking to async.
> You have the stream (socket) and the only thing which you should have
> to do is just send and recv. How it happens - async or blocking - is
> not up to library. I mean you have to support both cases as you do
> already, but you don't have to change the mode. Leave it to library's
> user. This small change will make life easier i believe. Right now, to
> cheat against Perl's GC, i create a new session before close a
> previous one. I don't like it. Just recv or send. Will it block or not
> - doesn't matter. User decides.
> 2011/10/28 Daniel Stenberg <>:
>> On Thu, 27 Oct 2011, Pavel Strashkin wrote:
>>> What happened to me is that i had one session (socket fd = 3) which was
>>> closed by server side so i handled it and closed everything on my side
>>> (sockets, ...). Net::SSH2 wrapper around the session had not been deleted
>>> yet so libssh2_session_free had not been called either.
>> Right, and here's the problem. You handed over the control of the socket to
>> libssh2, and then you closed it behind its back...
>>> I think libssh2 should never touch nonblock state or, at least, should set
>>> it to TRUE and forget about it till the end (i.e. nothing should happen
>>> inside libssh2_session_free).
>> The basic principles:
>> 1. the socket is handed over to libssh2 to handle when doing SSH operations
>> 2. libssh2 owns the socket as long as you haven't told it properly that
>> you're
>> done and want control back
>> 3. when libssh2 stops controlling the socket, it restores the original
>> blocking state of the socket so that to the application that passed in the
>> socket in step (1) it won't be any surprise
>> I don't think just skipping the restoring of the blocking state in step 3 is
>> going to save you. When you fiddle with the socket before libssh2 has been
>> told to give it up, you're out on very thin ice. We can't guarantee that
>> libssh2 won't have to do some other little thing on the socket before it
>> returns out and you as a user of libssh2 must not assume otherwise.
>> Or am I wrong?
>> --
>> /
>> _______________________________________________
>> libssh2-devel
> _______________________________________________
> libssh2-devel

Received on 2011-10-28