mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 08:08:50 -05:00
- Jeff Weber reported memory leaks with aborted SCP and SFTP transfers and
provided excellent repeat recipes. I fixed the cases I managed to reproduce but Jeff still got some (SCP) problems even after these fixes: http://curl.haxx.se/mail/lib-2008-05/0342.html
This commit is contained in:
parent
c62d55342d
commit
b49dcfb52b
6
CHANGES
6
CHANGES
@ -7,6 +7,12 @@
|
|||||||
Changelog
|
Changelog
|
||||||
|
|
||||||
|
|
||||||
|
Daniel Stenberg (28 May 2008)
|
||||||
|
- Jeff Weber reported memory leaks with aborted SCP and SFTP transfers and
|
||||||
|
provided excellent repeat recipes. I fixed the cases I managed to reproduce
|
||||||
|
but Jeff still got some (SCP) problems even after these fixes:
|
||||||
|
http://curl.haxx.se/mail/lib-2008-05/0342.html
|
||||||
|
|
||||||
Daniel Stenberg (26 May 2008)
|
Daniel Stenberg (26 May 2008)
|
||||||
- Bug report #1973352 (http://curl.haxx.se/bug/view.cgi?id=1973352) identified
|
- Bug report #1973352 (http://curl.haxx.se/bug/view.cgi?id=1973352) identified
|
||||||
how the HTTP redirect following code didn't properly follow to a new URL if
|
how the HTTP redirect following code didn't properly follow to a new URL if
|
||||||
|
@ -38,6 +38,7 @@ This release includes the following bugfixes:
|
|||||||
o several curl_multi_socket() fixes
|
o several curl_multi_socket() fixes
|
||||||
o builds fine for Haiku OS
|
o builds fine for Haiku OS
|
||||||
o follow redirect with only a new query string
|
o follow redirect with only a new query string
|
||||||
|
o SCP and SFTP memory leaks on aborted transfers
|
||||||
|
|
||||||
This release includes the following known bugs:
|
This release includes the following known bugs:
|
||||||
|
|
||||||
@ -60,6 +61,6 @@ advice from friends like these:
|
|||||||
Rafa Muyo, Andre Guibert de Bruet, Brock Noland, Sandor Feldi, Stefan Krause,
|
Rafa Muyo, Andre Guibert de Bruet, Brock Noland, Sandor Feldi, Stefan Krause,
|
||||||
David Shaw, Norbert Frese, Bart Whiteley, Jean-Francois Bertrand, Ben Van Hof,
|
David Shaw, Norbert Frese, Bart Whiteley, Jean-Francois Bertrand, Ben Van Hof,
|
||||||
Yuriy Sosov, Christopher Palow, Yang Tse, Liam Healy, Nikolai Kondrashov,
|
Yuriy Sosov, Christopher Palow, Yang Tse, Liam Healy, Nikolai Kondrashov,
|
||||||
David Rosenstrauch, Andreas Faerber, Scott McCreary
|
David Rosenstrauch, Andreas Faerber, Scott McCreary, Jeff Weber
|
||||||
|
|
||||||
Thanks! (and sorry if I forgot to mention someone)
|
Thanks! (and sorry if I forgot to mention someone)
|
||||||
|
79
lib/ssh.c
79
lib/ssh.c
@ -1698,6 +1698,20 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SSH_SFTP_SHUTDOWN:
|
case SSH_SFTP_SHUTDOWN:
|
||||||
|
/* during times we get here due to a broken transfer and then the
|
||||||
|
sftp_handle might not have been taken down so make sure that is done
|
||||||
|
before we proceed */
|
||||||
|
|
||||||
|
if(sshc->sftp_handle) {
|
||||||
|
rc = libssh2_sftp_close(sshc->sftp_handle);
|
||||||
|
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(rc < 0) {
|
||||||
|
infof(data, "Failed to close libssh2 file\n");
|
||||||
|
}
|
||||||
|
sshc->sftp_handle = NULL;
|
||||||
|
}
|
||||||
if(sshc->sftp_session) {
|
if(sshc->sftp_session) {
|
||||||
rc = libssh2_sftp_shutdown(sshc->sftp_session);
|
rc = libssh2_sftp_shutdown(sshc->sftp_session);
|
||||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||||
@ -1893,6 +1907,20 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SSH_SESSION_DISCONNECT:
|
case SSH_SESSION_DISCONNECT:
|
||||||
|
/* during weird times when we've been prematurely aborted, the channel
|
||||||
|
is still alive when we reach this state and we MUST kill the channel
|
||||||
|
properly first */
|
||||||
|
if(sshc->ssh_channel) {
|
||||||
|
rc = libssh2_channel_free(sshc->ssh_channel);
|
||||||
|
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if(rc < 0) {
|
||||||
|
infof(data, "Failed to free libssh2 scp subsystem\n");
|
||||||
|
}
|
||||||
|
sshc->ssh_channel = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if(sshc->ssh_session) {
|
if(sshc->ssh_session) {
|
||||||
rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
|
rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
|
||||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||||
@ -2152,23 +2180,25 @@ static CURLcode scp_disconnect(struct connectdata *conn)
|
|||||||
Curl_safefree(conn->data->state.proto.ssh);
|
Curl_safefree(conn->data->state.proto.ssh);
|
||||||
conn->data->state.proto.ssh = NULL;
|
conn->data->state.proto.ssh = NULL;
|
||||||
|
|
||||||
|
if(conn->proto.sshc.ssh_session) {
|
||||||
|
/* only if there's a session still around to use! */
|
||||||
|
|
||||||
state(conn, SSH_SESSION_DISCONNECT);
|
state(conn, SSH_SESSION_DISCONNECT);
|
||||||
|
|
||||||
result = ssh_easy_statemach(conn);
|
result = ssh_easy_statemach(conn);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode scp_done(struct connectdata *conn, CURLcode status,
|
/* generic done function for both SCP and SFTP called from their specific
|
||||||
bool premature)
|
done functions */
|
||||||
|
static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
bool done = FALSE;
|
bool done = FALSE;
|
||||||
(void)premature; /* not used */
|
|
||||||
(void)status; /* unused */
|
|
||||||
|
|
||||||
if(status == CURLE_OK) {
|
if(status == CURLE_OK) {
|
||||||
state(conn, SSH_SCP_DONE);
|
|
||||||
/* run the state-machine */
|
/* run the state-machine */
|
||||||
if(conn->data->state.used_interface == Curl_if_multi) {
|
if(conn->data->state.used_interface == Curl_if_multi) {
|
||||||
result = ssh_multi_statemach(conn, &done);
|
result = ssh_multi_statemach(conn, &done);
|
||||||
@ -2185,12 +2215,25 @@ static CURLcode scp_done(struct connectdata *conn, CURLcode status,
|
|||||||
|
|
||||||
if(done) {
|
if(done) {
|
||||||
struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
|
struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
|
||||||
|
|
||||||
Curl_safefree(sftp_scp->path);
|
Curl_safefree(sftp_scp->path);
|
||||||
sftp_scp->path = NULL;
|
sftp_scp->path = NULL;
|
||||||
Curl_pgrsDone(conn);
|
Curl_pgrsDone(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static CURLcode scp_done(struct connectdata *conn, CURLcode status,
|
||||||
|
bool premature)
|
||||||
|
{
|
||||||
|
(void)premature; /* not used */
|
||||||
|
|
||||||
|
if(status == CURLE_OK)
|
||||||
|
state(conn, SSH_SCP_DONE);
|
||||||
|
|
||||||
|
return ssh_done(conn, status);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2295,8 +2338,11 @@ static CURLcode sftp_disconnect(struct connectdata *conn)
|
|||||||
Curl_safefree(conn->data->state.proto.ssh);
|
Curl_safefree(conn->data->state.proto.ssh);
|
||||||
conn->data->state.proto.ssh = NULL;
|
conn->data->state.proto.ssh = NULL;
|
||||||
|
|
||||||
|
if(conn->proto.sshc.ssh_session) {
|
||||||
|
/* only if there's a session still around to use! */
|
||||||
state(conn, SSH_SFTP_SHUTDOWN);
|
state(conn, SSH_SFTP_SHUTDOWN);
|
||||||
result = ssh_easy_statemach(conn);
|
result = ssh_easy_statemach(conn);
|
||||||
|
}
|
||||||
|
|
||||||
DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
|
DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
|
||||||
|
|
||||||
@ -2307,12 +2353,8 @@ static CURLcode sftp_disconnect(struct connectdata *conn)
|
|||||||
static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
|
static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
|
||||||
bool premature)
|
bool premature)
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
|
||||||
bool done = FALSE;
|
|
||||||
struct ssh_conn *sshc = &conn->proto.sshc;
|
struct ssh_conn *sshc = &conn->proto.sshc;
|
||||||
|
|
||||||
(void)status; /* unused */
|
|
||||||
|
|
||||||
if(status == CURLE_OK) {
|
if(status == CURLE_OK) {
|
||||||
/* Before we shut down, see if there are any post-quote commands to send: */
|
/* Before we shut down, see if there are any post-quote commands to send: */
|
||||||
if(!status && !premature && conn->data->set.postquote) {
|
if(!status && !premature && conn->data->set.postquote) {
|
||||||
@ -2321,25 +2363,8 @@ static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
state(conn, SSH_SFTP_CLOSE);
|
state(conn, SSH_SFTP_CLOSE);
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
}
|
return ssh_done(conn, status);
|
||||||
else {
|
|
||||||
result = status;
|
|
||||||
done = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(done) {
|
|
||||||
Curl_pgrsDone(conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return number of sent bytes */
|
/* return number of sent bytes */
|
||||||
|
Loading…
Reference in New Issue
Block a user