Commit Graph

1583 Commits

Author SHA1 Message Date
Salvador Fandino
85a827d1bc Set default window size to 2MB
The default channel window size used until now was 256KB. This value is
too small and results on a bottleneck on real-life networks where
round-trip delays can easily reach 300ms.

The issue was not visible because the configured channel window size
was being ignored and a hard-coded value of ~22MB being used instead,
but that was fixed on a previous commit.

This patch just changes the default window size
(LIBSSH2_CHANNEL_WINDOW_DEFAULT) to 2MB. It is the same value used by
OpenSSH and in our opinion represents a good compromise between memory
used and transfer speed.

Performance tests were run to determine the optimum value. The details
and related discussion are available from the following thread on the
libssh2 mailing-list:

http://www.libssh2.org/mail/libssh2-devel-archive-2013-10/0018.shtml
http://article.gmane.org/gmane.network.ssh.libssh2.devel/6543

An excerpt follows:

"I have been running some transfer test and measuring their speed.

My setup was composed of a quad-core Linux machine running Ubuntu 13.10
x86_64 with a LXC container inside. The data transfers were performed
from the container to the host (never crossing through a physical
network device).

Network delays were simulated using the tc tool. And ping was used to
verify that they worked as intended during the tests.

The operation performed was the equivalent to the following ssh command:

  $ ssh container "dd bs=16K count=8K if=/dev/zero" >/dev/null

Though, establishment and closing of the SSH connection was excluded
from the timings.

I run the tests several times transferring files of sizes up to 128MB
and the results were consistent between runs.

The results corresponding to the 128MB transfer are available here:

https://docs.google.com/spreadsheet/ccc?key=0Ao1yRmX6PQQzdG5wSFlrZl9HRWNET3ZyN0hnaGo5ZFE&usp=sharing

It clearly shows that 256KB is too small as the default window size.
Moving to a 512MB generates a great improvement and after the 1MB mark
the returns rapidly diminish. Other factors (TCP window size, probably)
become more limiting than the channel window size

For comparison I also performed the same transfers using OpenSSH. Its
speed is usually on par with that of libssh2 using a window size of 1MB
(even if it uses a 2MB window, maybe it is less aggressive sending the
window adjust msgs)."

Signed-off-by: Salvador Fandino <sfandino@yahoo.com>
2013-10-27 13:50:20 +01:00
Salvador
1b3307dda0 _libssh2_channel_read: Honour window_size_initial
_libssh2_channel_read was using an arbitrary hard-coded limit to trigger
the window adjusting code. The adjustment used was also hard-coded and
arbitrary, 15MB actually, which would limit the usability of libssh2 on
systems with little RAM.

This patch, uses the window_size parameter passed to
libssh2_channel_open_ex (stored as remote.window_size_initial) plus the
buflen as the base for the trigger and the adjustment calculation.

The memory usage when using the default window size is reduced from 22MB
to 256KB per channel (actually, if compression is used, these numbers
should be incremented by ~50% to account for the errors between the
decompressed packet sizes and the predicted sizes).

My tests indicate that this change does not impact the performance of
transfers across localhost or a LAN, being it on par with that of
OpenSSH. On the other hand, it will probably slow down transfers on
networks with high bandwidth*delay when the default window size
(LIBSSH2_CHANNEL_WINDOW_DEFAULT=256KB) is used.

Signed-off-by: Salvador Fandino <sfandino@yahoo.com>
2013-10-27 13:49:33 +01:00
Salvador Fandino
85c6627c86 knownhosts: handle unknown key types
Store but don't use keys of unsupported types on the known_hosts file.

Currently, when libssh2 parses a known_host file containing keys of some
type it doesn't natively support, it stops reading the file and returns
an error.

That means, that the known_host file can not be safely shared with other
software supporting other key types (i.e. OpenSSH).

This patch adds support for handling keys of unknown type. It can read
and write them, even if they are never going to be matched.

At the source level the patch does the following things:

- add a new unknown key type LIBSSH2_KNOWNHOST_KEY_UNKNOWN

- add a new slot (key_type_name) on the known_host struct that is
used to store the key type in ascii form when it is not supported

- parse correctly known_hosts entries with unknown key types and
populate the key_type_name slot

- print correctly known_hosts entries of unknown type

- when checking a host key ignore keys that do not match the key

Fixes #276
2013-10-27 10:57:31 +01:00
Daniel Stenberg
c49cc8411f windows build: fix build errors
Fixes various link errors with VS2010

Reported-by: "kdekker"
Fixes #272
2013-10-16 23:23:26 +02:00
Daniel Stenberg
fa15fded72 man page: add missing function argument
for libssh2_userauth_publickey_fromfile_ex()

Reported-by: "pastey"

Fixes #262
2013-10-16 23:19:14 +02:00
Salvador
c2329aa09e Fix zlib deflate usage
Deflate may return Z_OK even when not all data has been compressed
if the output buffer becomes full.

In practice this is very unlikely to happen because the output buffer
size is always some KBs larger than the size of the data passed for
compression from the upper layers and I think that zlib never expands
the data so much, even on the worst cases.

Anyway, this patch plays on the safe side checking that the output
buffer is not exhausted.

Signed-off-by: Salvador <sfandino@yahoo.com>
2013-10-16 23:06:47 +02:00
Salvador
94077f7a58 comp_method_zlib_decomp: Improve buffer growing algorithm
The old algorithm was O(N^2), causing lots and lots of reallocations
when highly compressed data was transferred.

This patch implements a simpler one that just doubles the buffer size
everytime it is exhausted. It results in O(N) complexity.

Also a smaller inflate ratio is used to calculate the initial size (x4).

Signed-off-by: Salvador <sfandino@yahoo.com>
2013-10-16 23:05:40 +02:00
Salvador
55a8b10ad9 Fix zlib usage
Data may remain in zlib internal buffers when inflate() returns Z_OK
and avail_out == 0. In that case, inflate has to be called again.

Also, once all the data has been inflated, it returns Z_BUF_ERROR to
signal that the input buffer has been exhausted.

Until now, the way to detect that a packet payload had been completely
decompressed was to check that no data remained on the input buffer
but that didn't account for the case where data remained on the internal
zlib buffers.

That resulted in packets not being completely decompressed and the
missing data reappearing on the next packet, though the bug was masked
by the buffer allocation algorithm most of the time and only manifested
when transferring highly compressible data.

This patch fixes the zlib usage.

Signed-off-by: Salvador <sfandino@yahoo.com>
2013-10-16 22:55:29 +02:00
Salvador
27f9ac2549 _libssh2_channel_read: fix data drop when out of window
After filling the read buffer with data from the read queue, when the
window size was too small, "libssh2_channel_receive_window_adjust" was
called to increase it. In non-blocking mode that function could return
EAGAIN and, in that case, the EAGAIN was propagated upwards and the data
already read on the buffer lost.

The function was also moving between the two read states
"libssh2_NB_state_idle" and "libssh2_NB_state_created" both of which
behave in the same way (excepting a debug statment).

This commit modifies "_libssh2_channel_read" so that the
"libssh2_channel_receive_window_adjust" call is performed first (when
required) and if everything goes well, then it reads the data from the
queued packets into the read buffer.

It also removes the useless "libssh2_NB_state_created" read state.

Some rotted comments have also been updated.

Signed-off-by: Salvador <sfandino@yahoo.com>
2013-10-16 22:53:36 +02:00
Salvador Fandino
cdeef54967 window_size: redid window handling for flow control reasons
Until now, the window size (channel->remote.window_size) was being
updated just after receiving the packet from the transport layer.

That behaviour is wrong because the channel queue may grow uncontrolled
when data arrives from the network faster that the upper layer consumes
it.

This patch adds a new counter, read_avail, which keeps a count of the
bytes available from the packet queue for reading. Also, now the window
size is adjusted when the data is actually read by an upper layer.

That way, if the upper layer stops reading data, the window will
eventually fill and the remote host will stop sending data. When the
upper layers reads enough data, a window adjust packet is delivered and
the transfer resumes.

The read_avail counter is used to detect the situation when the remote
server tries to send data surpassing the window size. In that case, the
extra data is discarded.

Signed-off-by: Salvador <sfandino@yahoo.com>
2013-10-16 22:52:12 +02:00
Peter Stuge
42aefdba79 configure.ac: Call zlib zlib and not libz in text but keep option names 2013-09-15 21:13:27 +02:00
Peter Stuge
d41f5e40aa configure.ac: Reorder --with-* options in --help output 2013-09-15 21:13:03 +02:00
Peter Stuge
2df6cd6606 configure.ac: Rework crypto library detection
This further simplifies adding new crypto libraries.
2013-09-15 21:11:39 +02:00
Peter Stuge
d512b25f69 Clean up crypto library abstraction in build system and source code
libssh2 used to explicitly check for libgcrypt and default to OpenSSL.

Now all possible crypto libraries are checked for explicitly, making
the addition of further crypto libraries both simpler and cleaner.
2013-09-15 20:56:54 +02:00
Peter Stuge
b4f71fd25a configure.ac: Add zlib to Requires.private in libssh2.pc if using zlib 2013-09-15 20:36:58 +02:00
Peter Stuge
a5bf809b80 Revert "Added Windows Cryptography API: Next Generation based backend"
This reverts commit d385230e15.
2013-09-15 13:32:38 +02:00
Leif Salomonsson
2157e178a3 sftp_statvfs: fix for servers not supporting statfvs extension
Fixes issue arising when server does not support statfvs and or fstatvfs
extensions. sftp_statvfs() and sftp_fstatvfs() after this patch will
handle the case when SSH_FXP_STATUS is returned from server.
2013-09-07 23:11:54 +02:00
Marc Hoersken
d385230e15 Added Windows Cryptography API: Next Generation based backend 2013-09-07 22:38:14 +02:00
Kamil Dudka
61e40a32ff partially revert "window_size: explicit adjustments only"
This partially reverts commit 03ca902075
in order to fix extreme slowdown when uploading to localhost via SFTP.

I was able to repeat the issue on RHEL-7 on localhost only.  It did not
occur when uploading via network and it did not occur on a RHEL-6 box
with the same version of libssh2.

The problem was that sftp_read() used a read-ahead logic to figure out
the window_size, but sftp_packet_read() called indirectly from
sftp_write() did not use any read-ahead logic.
2013-09-07 22:30:34 +02:00
Daniel Stenberg
e6c46cc249 _libssh2_channel_write: client spins on write when window full
When there's no window to "write to", there's no point in waiting for
the socket to become writable since it most likely just will continue to
be.

Patch-by: ncm
Fixes #258
2013-09-07 13:41:14 +02:00
Daniel Stenberg
9f1b89e99b _libssh2_channel_forward_cancel: avoid memory leaks on error
Fixes #257
2013-09-07 13:37:59 +02:00
Daniel Stenberg
8da30ea4d4 _libssh2_packet_add: avoid using uninitialized memory
In _libssh2_packet_add, called by _libssh2_packet_read, a call to
_libssh2_packet_send that is supposed to send a one-byte message
SSH_MSG_REQUEST_FAILURE would send an uninitialized byte upon re-entry
if its call to _send returns _EAGAIN.

Fixes #259
2013-09-07 13:36:51 +02:00
Daniel Stenberg
ff6c01e959 _libssh2_channel_forward_cancel: accessed struct after free
... and the assignment was pointless anyway since the struct was about
to be freed. Bug introduced in dde2b094.

Fixes #268
2013-09-05 19:57:47 +02:00
Marc Hoersken
c910cd382d Fixed compilation using mingw-w64 2013-06-02 19:15:58 +02:00
Marc Hoersken
edd42304a2 knownhost.c: use LIBSSH2_FREE macro instead of free
Use LIBSSH2_FREE instead of free since
_libssh2_base64_encode uses LIBSSH2_ALLOC
2013-05-19 00:17:00 +02:00
Matthias Kerestesch
1ad20ac7d3 libssh2_agent_init: init ->fd to LIBSSH2_INVALID_SOCKET
... previously it was left at 0 which is a valid file descriptor!

Bug: https://trac.libssh2.org/ticket/265

Fixes #265
2013-05-18 23:03:18 +02:00
Daniel Stenberg
d7f9cd57c5 userauth_password: pass on the underlying error code
_libssh2_packet_requirev() may return different errors and we pass that
to the parent instead of rewriting it.

Bug: http://libssh2.org/mail/libssh2-devel-archive-2013-04/0029.shtml
Reported by: Cosmin
2013-05-18 23:03:18 +02:00
Marc Hoersken
16ef83dd81 libcrypt.c: Fix typo in _libssh2_rsa_sha1_sign() parameter type 2013-05-09 22:13:14 +02:00
Kamil Dudka
951904418b configure.ac: replace AM_CONFIG_HEADER with AC_CONFIG_HEADERS
Reported by: Quintus
Bug: https://trac.libssh2.org/ticket/261
2013-05-04 22:52:41 +02:00
Guenter Knauf
80e5e20b00 Fixed copyright string for NetWare build. 2013-04-12 18:00:29 +02:00
Richard W.M. Jones
6e0d757f24 sftp: Add support for fsync (OpenSSH extension).
The new libssh2_sftp_fsync API causes data and metadata in the
currently open file to be committed to disk at the server.

This is an OpenSSH extension to the SFTP protocol.  See:

https://bugzilla.mindrot.org/show_bug.cgi?id=1798
2013-04-09 16:25:54 +02:00
Richard W.M. Jones
a12f3ffab5 sftp: statvfs: Along error path, reset the correct 'state' variable. 2013-04-08 22:11:15 +02:00
Richard W.M. Jones
486bb37621 sftp: seek: Don't flush buffers on same offset
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
2013-03-27 15:46:51 +01:00
Guenter Knauf
fe347a702f Updated dependency libs. 2013-02-09 01:38:53 +01:00
Guenter Knauf
07615610ba Fixed tool macro names. 2012-12-04 11:52:08 +01:00
Seth Willits
5aa7b29758 compiler warnings: typecast strlen in macros
... in macro parameters to avoid compiler warnings about lost precision.

Several macros in libssh2.h call strlen and pass the result directly to
unsigned int parameters of other functions, which warns about precision
loss because strlen returns size_t which is unsigned long on at least
some platforms (such as OS X). The fix is to simply typecast the
strlen() result to unsigned int.
2012-11-29 20:30:04 +01:00
Daniel Stenberg
a67ff056e6 libssh2.h: bump version to 1.4.4-DEV 2012-11-27 23:03:45 +01:00
Daniel Stenberg
f1cfa55b60 RELEASE-NOTES: fixed for 1.4.3 2012-11-27 22:44:09 +01:00
Daniel Stenberg
437a3b75ec sftp_read: return error if a too large package arrives 2012-11-20 08:23:39 +01:00
Peter Stuge
a3ad635db4 Only define _libssh2_dsa_*() functions when building with DSA support 2012-11-13 00:11:47 +01:00
Guenter Knauf
e5c5408564 Added .def file to output. 2012-11-08 18:57:14 +01:00
Kamil Dudka
fe8f3deb48 libssh2_hostkey_hash.3: update the description of return value
The function returns NULL also if the hash algorithm is not available.
2012-11-01 15:04:07 +01:00
Guenter Knauf
d49b8f303a Fixed mode acciedently committed. 2012-10-24 03:41:10 +02:00
Guenter Knauf
6f8777505f Ignore generated file. 2012-10-24 03:29:50 +02:00
Guenter Knauf
52b8da7dfa Added hack to make use of Makefile.inc.
This should avoid further maintainance of the objects list.
2012-10-24 03:22:07 +02:00
Guenter Knauf
de7b5d3bc0 Fixed MSVC NMakefile.
Added missing source files; added resource for DLL.
2012-10-24 02:37:55 +02:00
Kamil Dudka
b31e35aba6 examples: use stderr for messages, stdout for data
Reported by: Karel Srot
Bug: https://bugzilla.redhat.com/867462
2012-10-22 13:39:58 +02:00
Kamil Dudka
e2bb780d77 openssl: do not leak memory when handling errors
,.. in aes_ctr_init().  Detected by Coverity.
2012-10-08 14:30:40 +02:00
Kamil Dudka
a8cfc708c5 channel: fix possible NULL dereference
... in libssh2_channel_get_exit_signal().  Detected by Coverity.
2012-10-08 14:19:23 +02:00
Kamil Dudka
9f6fd5af82 Revert "aes: the init function fails when OpenSSL has AES support"
This partially reverts commit f4f2298ef3.

We need to use the EVP_aes_???_ctr() functions in FIPS mode.
2012-09-17 09:48:07 +02:00