If libssh2_session_free is called without the channel being freed
previously by libssh2_channel_free a memory leak could occur.
A mismatch of states variables in session_free() prevent the call to
libssh2_channel_free function. session->state member is used instead of
session->free_state.
It causes a leak of around 600 bytes on every connection on my systems
(Linux, x64 and PPC).
(Debugging done under contract for Accedian Networks)
Fixes#246
When using libssh2 to perform an SFTP file transfer from the "JSCAPE MFT
Server" (http://www.jscape.com) the transfer failed. The default JSCAPE
configuration is to enforce zlib compression on SSH2 sessions so the
session was compressed. The relevant part of the debug trace contained:
[libssh2] 1.052750 Transport: unhandled zlib error -5
[libssh2] 1.052750 Failure Event: -29 - decompression failure
The trace comes from comp_method_zlib_decomp() in comp.c. The "unhandled
zlib error -5" is the status returned from the zlib function
inflate(). The -5 status corresponds to "Z_BUF_ERROR".
The inflate() function takes a pointer to a z_stream structure and
"inflates" (decompresses) as much as it can. The relevant fields of the
z_stream structure are:
next_in - pointer to the input buffer containing compressed data
avail_in - the number of bytes available at next_in
next_out - pointer to the output buffer to be filled with uncompressed
data
avail_out - how much space available at next_out
To decompress data you set up a z_stream struct with the relevant fields
filled in and pass it to inflate(). On return the fields will have been
updated so next_in and avail_in show how much compressed data is yet to
be processed and next_out and avail_out show how much space is left in
the output buffer.
If the supplied output buffer is too small then on return there will be
compressed data yet to be processed (avail_in != 0) and inflate() will
return Z_OK. In this case the output buffer must be grown, avail_out
updated and inflate() called again.
If the supplied output buffer was big enough then on return the
compressed data will have been exhausted (avail_in == 0) and inflate()
will return Z_OK, so the data has all been uncompressed.
There is a corner case where inflate() makes no progress. That is, there
may be unprocessed compressed data and space available in the output
buffer and yet the function does nothing. In this case inflate() will
return Z_BUF_ERROR. From the zlib documentation and the source code it
is not clear under what circumstances this happens. It could be that it
needs to write multiple bytes (all in one go) from its internal state to
the output buffer before processing the next chunk of input but but
can't because there is not enough space (though my guesses as to the
cause are not really relevant). Recovery from Z_BUF_ERROR is pretty
simple - just grow the output buffer, update avail_out and call
inflate() again.
The comp_method_zlib_decomp() function does not handle the case when
inflate() returns Z_BUF_ERROR. It treats it as a non-recoverable error
and basically aborts the session.
Fixes#240
Changed to use Windows commandline tools instead of
GNU tools when compiling on Windows. Fixed dist and
dev targets. Enabled nlmconv error for unresolved
symbols.
Usually a format macro should hold the whole format, otherwise
it should be named a prefix. Also fixed usage of this macro in
scp.c for a signed var where it was used as prefix for unsigned.
Rationale: Everything else in this file states a fact about the win32
platform that is unconditional for that platform. There is nothing
unconditional about the presence of zlib. It is neither included with
Windows nor with the platform SDK. Therefore, this is not an appropriate
place to assert its presence. Especially as, once asserted, it cannot be
overridden using a compiler flag.
In contrast, if it is omitted, then it can easily be reasserted by adding
a compiler flag defining LIBSSH2_HAVE_ZLIB.
sftp_packet_add takes ownership of the packet passed to it and (now that we
handle zombies) might free the packet. sftp_packet_read uses the packet type
byte as its return code but by this point sftp_packet_add might have freed
it. This change fixes the problem by caching the packet type before calling
sftp_packet_add.
I don't understand why sftp_packet_read uses the packet type as its return
code. A future change might get rid of this entirely.
As this function is called when the SFTP session is closed, it needs to
also kill all zombies left in the SFTP session to avoid leaking memory
just in case some zombie would still be in there.
When flushing the packetlist, we must only add the request as a zombie
if no response has already been received. Otherwise we could wrongly
make it a zombie even though the response was already received and then
we'd get a zombie stuck there "forever"...
Since the sftp_packetlist_flush() function will move all the existing
FXP_READ requests in this handle to the zombie list we must first remove
this just received packet as it is clearly not a zombie.
Exactly as the comment in the code said, checking the return code from
sftp_packet_read() with <= was wrong and it should be < 0. With the new
filtering on incoming packets that are "zombies" we can now see this
getting zero returned.
In order to be fast, sftp_read sends many read requests at once. With a small
file, this can mean that when EOF is received back, many of these requests are
still outstanding. Responses arriving after we close the file and abandon the
file handle are queued in the SFTP packet queue and never collected. This
causes transfer speed to drop as a progressively longer queue must be searched
for every packet.
This change introduces a zombie request-ID list in the SFTP session that is
used to recognise these outstanding requests and prevent them being added to
the queue.
libcrypto on win32 now depends on gdi32.dll, so move the OpenSSL LDLIBS
block to before the compiler definitions, so that libcrypto gets added
first, and then add -lgdi32 into the following common LDLIBS for gcc.
Examples are built by default. Any of the following options on the
configure command line will skip building them:
--disable-examples-build
--enable-examples-build=no
--enable-examples-build=false
If the filename parameter for file_read_publickey() was the name of a
directory instead of a file then libssh2 would spin trying to fgetc()
from the FILE * for the opened directory when trying to determine the
length of the encoded public key, since fgetc() can't report errors.
Use fread() instead to correctly detect this error condition along
with many others.
This fixes the problem reported in
http://www.libssh2.org/mail/libssh2-devel-archive-2012-04/0021.shtml
Reported-by: Oleksiy Zagorskyi <zalex_ua@i.ua>
When calling _libssh2_channel_receive_window_adjust() internally, we now
always use the 'force' option to prevent libssh2 to avoid sending the
update if the update isn't big enough.
It isn't fully analyzed but we have seen corner cases which made a
necessary window update not get send due to this and then the other side
doesn't send data our side then sits waiting for forever.