mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-09 09:54:25 +09:00
Fixed blocking bug in channel_poll
This commit is contained in:
@@ -143,6 +143,6 @@ struct ssh_session_struct {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int ssh_handle_packets(ssh_session session);
|
int ssh_handle_packets(ssh_session session, int timeout);
|
||||||
|
|
||||||
#endif /* SESSION_H_ */
|
#endif /* SESSION_H_ */
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ static int ask_userauth(ssh_session session) {
|
|||||||
do {
|
do {
|
||||||
rc=ssh_service_request(session,"ssh-userauth");
|
rc=ssh_service_request(session,"ssh-userauth");
|
||||||
if(rc==SSH_AGAIN)
|
if(rc==SSH_AGAIN)
|
||||||
ssh_handle_packets(session);
|
ssh_handle_packets(session,-1);
|
||||||
} while(rc==SSH_AGAIN);
|
} while(rc==SSH_AGAIN);
|
||||||
leave_function();
|
leave_function();
|
||||||
return rc;
|
return rc;
|
||||||
@@ -202,7 +202,7 @@ static int wait_auth_status(ssh_session session) {
|
|||||||
enter_function();
|
enter_function();
|
||||||
|
|
||||||
while (session->auth_state == SSH_AUTH_STATE_NONE) {
|
while (session->auth_state == SSH_AUTH_STATE_NONE) {
|
||||||
ssh_handle_packets(session);
|
ssh_handle_packets(session,-1);
|
||||||
}
|
}
|
||||||
switch(session->auth_state){
|
switch(session->auth_state){
|
||||||
case SSH_AUTH_STATE_ERROR:
|
case SSH_AUTH_STATE_ERROR:
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ static int channel_open(ssh_channel channel, const char *type_c, int window,
|
|||||||
/* Todo: fix this into a correct loop */
|
/* Todo: fix this into a correct loop */
|
||||||
/* wait until channel is opened by server */
|
/* wait until channel is opened by server */
|
||||||
while(!channel->open){
|
while(!channel->open){
|
||||||
ssh_handle_packets(session);
|
ssh_handle_packets(session,-1);
|
||||||
}
|
}
|
||||||
leave_function();
|
leave_function();
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
@@ -934,7 +934,7 @@ int channel_write_common(ssh_channel channel, const void *data,
|
|||||||
/* What happens when the channel window is zero? */
|
/* What happens when the channel window is zero? */
|
||||||
while(channel->remote_window == 0) {
|
while(channel->remote_window == 0) {
|
||||||
/* parse every incoming packet */
|
/* parse every incoming packet */
|
||||||
if (ssh_handle_packets(session) == SSH_ERROR) {
|
if (ssh_handle_packets(session,-1) == SSH_ERROR) {
|
||||||
leave_function();
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
@@ -1157,7 +1157,7 @@ static int channel_request(ssh_channel channel, const char *request,
|
|||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
while(channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING){
|
while(channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING){
|
||||||
ssh_handle_packets(session);
|
ssh_handle_packets(session,-1);
|
||||||
}
|
}
|
||||||
/* we received something */
|
/* we received something */
|
||||||
switch (channel->request_state){
|
switch (channel->request_state){
|
||||||
@@ -1460,7 +1460,7 @@ static ssh_channel channel_accept(ssh_session session, int channeltype,
|
|||||||
|
|
||||||
for (t = timeout_ms; t >= 0; t -= 50)
|
for (t = timeout_ms; t >= 0; t -= 50)
|
||||||
{
|
{
|
||||||
ssh_handle_packets(session);
|
ssh_handle_packets(session,-1);
|
||||||
|
|
||||||
if (session->ssh_message_list) {
|
if (session->ssh_message_list) {
|
||||||
iterator = ssh_list_get_iterator(session->ssh_message_list);
|
iterator = ssh_list_get_iterator(session->ssh_message_list);
|
||||||
@@ -1594,7 +1594,7 @@ static int global_request(ssh_session session, const char *request,
|
|||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
while(session->global_req_state == SSH_CHANNEL_REQ_STATE_PENDING){
|
while(session->global_req_state == SSH_CHANNEL_REQ_STATE_PENDING){
|
||||||
rc=ssh_handle_packets(session);
|
rc=ssh_handle_packets(session,-1);
|
||||||
if(rc==SSH_ERROR){
|
if(rc==SSH_ERROR){
|
||||||
session->global_req_state = SSH_CHANNEL_REQ_STATE_ERROR;
|
session->global_req_state = SSH_CHANNEL_REQ_STATE_ERROR;
|
||||||
break;
|
break;
|
||||||
@@ -1953,7 +1953,7 @@ int channel_read_buffer(ssh_channel channel, ssh_buffer buffer, uint32_t count,
|
|||||||
/* Stop reading when buffer is full enough */
|
/* Stop reading when buffer is full enough */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ssh_handle_packets(session);
|
ssh_handle_packets(session,-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(channel->local_window < WINDOWLIMIT) {
|
if(channel->local_window < WINDOWLIMIT) {
|
||||||
@@ -2059,7 +2059,7 @@ int channel_read(ssh_channel channel, void *dest, uint32_t count, int is_stderr)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssh_handle_packets(session);
|
ssh_handle_packets(session,-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel->local_window < WINDOWLIMIT) {
|
if (channel->local_window < WINDOWLIMIT) {
|
||||||
@@ -2148,9 +2148,10 @@ int channel_poll(ssh_channel channel, int is_stderr){
|
|||||||
stdbuf = channel->stderr_buffer;
|
stdbuf = channel->stderr_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (buffer_get_rest_len(stdbuf) == 0 && channel->remote_eof == 0) {
|
if (buffer_get_rest_len(stdbuf) == 0 && channel->remote_eof == 0) {
|
||||||
if (ssh_handle_packets(channel->session) <= 0) {
|
if (ssh_handle_packets(channel->session,0)==SSH_ERROR) {
|
||||||
break;
|
leave_function();
|
||||||
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2193,7 +2194,7 @@ int channel_get_exit_status(ssh_channel channel) {
|
|||||||
|
|
||||||
while (channel->remote_eof == 0 || channel->exit_status == -1) {
|
while (channel->remote_eof == 0 || channel->exit_status == -1) {
|
||||||
/* Parse every incoming packet */
|
/* Parse every incoming packet */
|
||||||
if (ssh_handle_packets(channel->session) != SSH_OK) {
|
if (ssh_handle_packets(channel->session,-1) != SSH_OK) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (channel->open == 0) {
|
if (channel->open == 0) {
|
||||||
@@ -2225,7 +2226,7 @@ static int channel_protocol_select(ssh_channel *rchans, ssh_channel *wchans,
|
|||||||
chan = rchans[i];
|
chan = rchans[i];
|
||||||
|
|
||||||
while (chan->open && ssh_socket_data_available(chan->session->socket)) {
|
while (chan->open && ssh_socket_data_available(chan->session->socket)) {
|
||||||
ssh_handle_packets(chan->session);
|
ssh_handle_packets(chan->session,-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((chan->stdout_buffer && buffer_get_len(chan->stdout_buffer) > 0) ||
|
if ((chan->stdout_buffer && buffer_get_len(chan->stdout_buffer) > 0) ||
|
||||||
|
|||||||
@@ -692,7 +692,7 @@ int ssh_connect(ssh_session session) {
|
|||||||
session->session_state != SSH_SESSION_STATE_AUTHENTICATING){
|
session->session_state != SSH_SESSION_STATE_AUTHENTICATING){
|
||||||
/* loop until SSH_SESSION_STATE_BANNER_RECEIVED or
|
/* loop until SSH_SESSION_STATE_BANNER_RECEIVED or
|
||||||
* SSH_SESSION_STATE_ERROR */
|
* SSH_SESSION_STATE_ERROR */
|
||||||
ssh_handle_packets(session);
|
ssh_handle_packets(session,-1);
|
||||||
ssh_log(session,SSH_LOG_PACKET,"ssh_connect: Actual state : %d",session->session_state);
|
ssh_log(session,SSH_LOG_PACKET,"ssh_connect: Actual state : %d",session->session_state);
|
||||||
}
|
}
|
||||||
leave_function();
|
leave_function();
|
||||||
|
|||||||
@@ -705,7 +705,7 @@ ssh_message ssh_message_get(ssh_session session) {
|
|||||||
ssh_message msg = NULL;
|
ssh_message msg = NULL;
|
||||||
enter_function();
|
enter_function();
|
||||||
do {
|
do {
|
||||||
if (ssh_handle_packets(session) == SSH_ERROR) {
|
if (ssh_handle_packets(session,-1) == SSH_ERROR) {
|
||||||
leave_function();
|
leave_function();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -386,7 +386,7 @@ static int dh_handshake_server(ssh_session session) {
|
|||||||
ssh_private_key prv;
|
ssh_private_key prv;
|
||||||
/* waiting for SSH_MSG_KEXDH_INIT */
|
/* waiting for SSH_MSG_KEXDH_INIT */
|
||||||
while(session->dh_handshake_state != DH_STATE_INIT_SENT){
|
while(session->dh_handshake_state != DH_STATE_INIT_SENT){
|
||||||
ssh_handle_packets(session);
|
ssh_handle_packets(session,-1);
|
||||||
}
|
}
|
||||||
/* received SSH_MSG_KEXDH_INIT */
|
/* received SSH_MSG_KEXDH_INIT */
|
||||||
|
|
||||||
@@ -489,7 +489,7 @@ static int dh_handshake_server(ssh_session session) {
|
|||||||
ssh_log(session, SSH_LOG_PACKET, "SSH_MSG_NEWKEYS sent");
|
ssh_log(session, SSH_LOG_PACKET, "SSH_MSG_NEWKEYS sent");
|
||||||
|
|
||||||
while(session->dh_handshake_state != DH_STATE_FINISHED)
|
while(session->dh_handshake_state != DH_STATE_FINISHED)
|
||||||
ssh_handle_packets(session);
|
ssh_handle_packets(session,-1);
|
||||||
|
|
||||||
if (generate_session_keys(session) < 0) {
|
if (generate_session_keys(session) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -265,9 +265,13 @@ void ssh_set_fd_except(ssh_session session) {
|
|||||||
* @brief polls the current session for an event and call the
|
* @brief polls the current session for an event and call the
|
||||||
* appropriate callbacks. Will block until one event happens.
|
* appropriate callbacks. Will block until one event happens.
|
||||||
* @param session session handle.
|
* @param session session handle.
|
||||||
|
* @param timeout An upper limit on the time for which
|
||||||
|
* ssh_handle_packets() will block, in milliseconds.
|
||||||
|
* Specifying a negative value means an infinite timeout.
|
||||||
|
* This parameter is passed to the poll() function.
|
||||||
* @return SSH_OK if there are no error, SSH_ERROR otherwise.
|
* @return SSH_OK if there are no error, SSH_ERROR otherwise.
|
||||||
*/
|
*/
|
||||||
int ssh_handle_packets(ssh_session session) {
|
int ssh_handle_packets(ssh_session session, int timeout) {
|
||||||
ssh_poll_handle spoll;
|
ssh_poll_handle spoll;
|
||||||
ssh_poll_ctx ctx;
|
ssh_poll_ctx ctx;
|
||||||
if(session==NULL || session->socket==NULL)
|
if(session==NULL || session->socket==NULL)
|
||||||
@@ -279,7 +283,7 @@ int ssh_handle_packets(ssh_session session) {
|
|||||||
ctx=ssh_get_global_poll_ctx(session);
|
ctx=ssh_get_global_poll_ctx(session);
|
||||||
ssh_poll_ctx_add(ctx,spoll);
|
ssh_poll_ctx_add(ctx,spoll);
|
||||||
}
|
}
|
||||||
ssh_poll_ctx_dopoll(ctx,-1);
|
ssh_poll_ctx_dopoll(ctx,timeout);
|
||||||
leave_function();
|
leave_function();
|
||||||
if (session->session_state != SSH_SESSION_STATE_ERROR)
|
if (session->session_state != SSH_SESSION_STATE_ERROR)
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
|
|||||||
Reference in New Issue
Block a user