1
0
mirror of https://github.com/libssh2/libssh2.git synced 2025-11-02 10:53:16 +03:00

If SFTP fails to initialize, do not busy loop waiting for IO to happen (#720)

Currently SFTP's init will busy loop waiting for the channel to close,
even if the underlying transport returns EAGAIN. While this works for
sockets, it might not work out if you have a different transport that
needs to do some additional processing on the side.

Integration-patches-by: Viktor Szakats
This commit is contained in:
Miguel de Icaza
2023-04-26 14:51:19 -04:00
committed by GitHub
parent 592e2b37fa
commit 33dddd2f8a
3 changed files with 20 additions and 9 deletions

View File

@@ -262,6 +262,7 @@ typedef enum
libssh2_NB_state_jump3,
libssh2_NB_state_jump4,
libssh2_NB_state_jump5,
libssh2_NB_state_error_closing,
libssh2_NB_state_end,
libssh2_NB_state_jumpauthagent
} libssh2_nonblocking_states;

View File

@@ -894,6 +894,22 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
}
}
if(session->sftpInit_state == libssh2_NB_state_error_closing) {
rc = _libssh2_channel_free(session->sftpInit_channel);
if(rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block closing channel");
return NULL;
}
session->sftpInit_channel = NULL;
if(session->sftpInit_sftp) {
LIBSSH2_FREE(session, session->sftpInit_sftp);
session->sftpInit_sftp = NULL;
}
session->sftpInit_state = libssh2_NB_state_idle;
return NULL;
}
rc = sftp_packet_require(sftp_handle, SSH_FXP_VERSION,
0, &data, &data_len, 5);
if(rc == LIBSSH2_ERROR_EAGAIN) {
@@ -970,14 +986,7 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
return sftp_handle;
sftp_init_error:
while(_libssh2_channel_free(session->sftpInit_channel) ==
LIBSSH2_ERROR_EAGAIN);
session->sftpInit_channel = NULL;
if(session->sftpInit_sftp) {
LIBSSH2_FREE(session, session->sftpInit_sftp);
session->sftpInit_sftp = NULL;
}
session->sftpInit_state = libssh2_NB_state_idle;
session->sftpInit_state = libssh2_NB_state_error_closing;
return NULL;
}

View File

@@ -777,7 +777,8 @@ send_existing(LIBSSH2_SESSION *session, const unsigned char *data,
we don't add this one up until the previous one has been sent. To
make the caller really notice his/hers flaw, we return error for
this case */
return LIBSSH2_ERROR_BAD_USE;
_libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
"Address is different, but will resume nonetheless"));
}
*ret = 1; /* set to make our parent return */