Commit f31760e6 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

ssh: ignore timeouts during disconnect

... as otherwise it risks not cleaning up the libssh2 handle properly
which leads to memory leak!

Assisted-by: Joel Depooter

Closes #1495
Closes #1479

Bug: https://curl.haxx.se/mail/lib-2017-04/0024.html
parent e5491e0f
Loading
Loading
Loading
Loading
+15 −12
Original line number Diff line number Diff line
@@ -113,6 +113,7 @@
        libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \
                                (t), (m), LIBSSH2_SFTP_REALPATH)


/* Local functions: */
static const char *sftp_libssh2_strerror(int err);
static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
@@ -2815,7 +2816,7 @@ static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
}

static CURLcode ssh_block_statemach(struct connectdata *conn,
                                   bool duringconnect)
                                    bool disconnect)
{
  struct ssh_conn *sshc = &conn->proto.sshc;
  CURLcode result = CURLE_OK;
@@ -2830,6 +2831,7 @@ static CURLcode ssh_block_statemach(struct connectdata *conn,
    if(result)
      break;

    if(!disconnect) {
      if(Curl_pgrsUpdate(conn))
        return CURLE_ABORTED_BY_CALLBACK;

@@ -2837,11 +2839,12 @@ static CURLcode ssh_block_statemach(struct connectdata *conn,
      if(result)
        break;

    left = Curl_timeleft(data, NULL, duringconnect);
      left = Curl_timeleft(data, NULL, FALSE);
      if(left < 0) {
        failf(data, "Operation timed out");
        return CURLE_OPERATION_TIMEDOUT;
      }
    }

#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
    if(!result && block) {
@@ -3056,7 +3059,7 @@ static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)

    state(conn, SSH_SESSION_DISCONNECT);

    result = ssh_block_statemach(conn, FALSE);
    result = ssh_block_statemach(conn, TRUE);
  }

  return result;
@@ -3210,7 +3213,7 @@ static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
  if(conn->proto.sshc.ssh_session) {
    /* only if there's a session still around to use! */
    state(conn, SSH_SFTP_SHUTDOWN);
    result = ssh_block_statemach(conn, FALSE);
    result = ssh_block_statemach(conn, TRUE);
  }

  DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));