From 03ca98b0df0f0bd599cbd5e293dedb648dae8faf Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Wed, 17 Dec 2008 12:32:41 +0000
Subject: [PATCH] - SCP and SFTP with the multi interface had the same flaw:
 the 'DONE'   operation didn't complete properly if the EAGAIN equivalent was
 returned but   libcurl would simply continue with a half-completed close
 operation   performed. This ruined persistent connection re-use and cause
 some   SSH-protocol errors in general. The correction is unfortunately adding
 a   blocking function - doing it entirely non-blocking should be considered
 for   a better fix.

---
 CHANGES       |  9 +++++++++
 RELEASE-NOTES |  1 +
 lib/ssh.c     | 32 +++++++++++++-------------------
 3 files changed, 23 insertions(+), 19 deletions(-)

diff --git a/CHANGES b/CHANGES
index 5bc7c64c97..618c4f97c7 100644
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,15 @@
 
                                   Changelog
 
+Daniel Stenberg (17 Dec 2008)
+- SCP and SFTP with the multi interface had the same flaw: the 'DONE'
+  operation didn't complete properly if the EAGAIN equivalent was returned but
+  libcurl would simply continue with a half-completed close operation
+  performed. This ruined persistent connection re-use and cause some
+  SSH-protocol errors in general. The correction is unfortunately adding a
+  blocking function - doing it entirely non-blocking should be considered for
+  a better fix.
+
 Gisle Vanem (16 Dec 2008)
 - Added the possibility to use the Watt-32 tcp/ip stack under Windows.
   The change simply involved adding a USE_WATT32 section in the
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index 6183d4364c..a4202cc5de 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -31,6 +31,7 @@ This release includes the following bugfixes:
  o curl_easy_duphandle() doesn't try to duplicate the connection cache pointer
  o build failure on OS/400 when enabling IPv6
  o better detection of SFTP failures
+ o improved connection re-use for subsequent SCP and SFTP trnasfers 
 
 This release includes the following known bugs:
 
diff --git a/lib/ssh.c b/lib/ssh.c
index c97d0c7e88..08ccf0a727 100644
--- a/lib/ssh.c
+++ b/lib/ssh.c
@@ -2309,30 +2309,24 @@ static CURLcode scp_disconnect(struct connectdata *conn)
 static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
 {
   CURLcode result = CURLE_OK;
-  bool done = FALSE;
+  struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
 
   if(status == CURLE_OK) {
-    /* run the state-machine */
-    if(conn->data->state.used_interface == Curl_if_multi) {
-      result = ssh_multi_statemach(conn, &done);
-    }
-    else {
-      result = ssh_easy_statemach(conn);
-      done = TRUE;
-    }
+    /* run the state-machine
+
+       TODO: when the multi interface this _really_ should be using the
+       ssh_multi_statemach function but we have no general support for
+       non-blocking DONE operations, not in the multi state machine and with
+       Curl_done() invokes on several places in the code!
+    */
+    result = ssh_easy_statemach(conn);
   }
-  else {
+  else
     result = status;
-    done = TRUE;
-  }
-
-  if(done) {
-    struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
 
-    Curl_safefree(sftp_scp->path);
-    sftp_scp->path = NULL;
-    Curl_pgrsDone(conn);
-  }
+  Curl_safefree(sftp_scp->path);
+  sftp_scp->path = NULL;
+  Curl_pgrsDone(conn);
 
   return result;
 }
-- 
GitLab