Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

connection reuse does not work with libssh #3491

felixhaedicke opened this issue Jan 22, 2019 · 3 comments

connection reuse does not work with libssh #3491

felixhaedicke opened this issue Jan 22, 2019 · 3 comments


Copy link

When calling curl_easy_perform() more than once on one easy handle for a SSH connection (sftp:// URL), the connection is not reused. See example code below.

It seems to try reusing the connection, but then says that the connection is dead. See excerpt from the output of my example program below.

curl/libcurl version

Compiled curl on Debian GNU/Linux:
curl 7.64.0-DEV (x86_64-pc-linux-gnu) libcurl/7.64.0-DEV OpenSSL/1.1.1a zlib/1.2.11 libidn2/2.0.5 libssh/0.8.6/openssl/zlib
Release-Date: [unreleased]
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS Debug TrackMemory IDN IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP UnixSockets HTTPS-proxy

Same on Windows with CURL 7.63.0 on Windows 7, compiled with Visual Studio 2017 and libssh 0.8.6

tested operating systems

  • Debian GNU/Linux sid
  • Windows 7

example program source code

#include <assert.h>
#include <stdio.h>

#include <curl/curl.h>

int main()
  CURLcode status = curl_global_init(CURL_GLOBAL_ALL);
  assert(CURLE_OK == status);

  CURL* curl = curl_easy_init();

  status = curl_easy_setopt(curl, CURLOPT_URL, "sftp://localhost/~/");
  assert(CURLE_OK == status);
  status = curl_easy_setopt(curl, CURLOPT_VERBOSE, (long) 1);
  assert(CURLE_OK == status);

  status = curl_easy_perform(curl);
  assert(CURLE_OK == status);

  puts("\n\nSecond curl_easy_perform() call...\n\n");

  status = curl_easy_perform(curl);
  assert(CURLE_OK == status);


  return 0;

excerpt from the output of the example program

* SFTP DONE done
* SSH 0x556ccafe29c0 state change from SSH_SFTP_CLOSE to SSH_STOP (line 1651)
* Connection #0 to host localhost left intact
* Expire cleared (transfer 0x556ccafe41a8)

Second curl_easy_perform() call...

* Expire in 0 ms for 6 (transfer 0x556ccafe41a8)
* STATE: INIT => CONNECT handle 0x556ccafe41a8; line 1443 (connection #-5000)
* Found bundle for host localhost: 0x556ccafe0418 [serially]
* Connection 0 seems to be dead!
* The cache now contains 0 members
* SSH DISCONNECT starts now
Copy link
Contributor Author

Looks like the check for the connection does not work correctly for libssh connections.

in url.c:

dead = SocketIsDead(conn->sock[FIRSTSOCKET]);

I tried deactivating this check, and the connection is successfully reused.
Which meaning does conn->sock[FIRSTSOCKET] have for libssh connections? This is not the socket which we would get using ssh_get_fd().

Copy link

bagder commented Jan 23, 2019

conn->sock[FIRSTSOCKET] should be the main socket libssh uses. Maybe that's a clue into what's wrong... /cc @nmav

Copy link

nmav commented Jan 23, 2019

/cc @kdudka @ansasaki

felixhaedicke added a commit to felixhaedicke/curl that referenced this issue Jan 23, 2019
By default, libssh creates a new socket, instead of using the socket
created by curl for SSH connections.

Pass the socket created by curl to libssh using ssh_options_set() with
SSH_OPTIONS_FD directly after ssh_new(). So libssh uses our socket
instead of creating a new one.

This approach is very similar to what is done in the libssh2 code, where
the socket created by curl is passed to libssh2 when
libssh2_session_startup() is called.

Fixes curl#3491
@bagder bagder closed this as completed in 15c94b3 Jan 24, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Apr 24, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Successfully merging a pull request may close this issue.

3 participants