- 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.
This commit is contained in:
32
lib/ssh.c
32
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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user