Page MenuHomePhabricator

ssh_disconnect does not properly reset the pending_call_state to SSH_PENDING_CALL_NONE
Closed, ResolvedPublic


Calling ssh_disconnect on a session while it is pending on the completion of a non-blocking connection leaves the session in a non-reusable, invalid state. If ssh_disconnect is called before setting the pending_call_state to SSH_PENDING_CALL_NONE (client.c:632), which typically happens when client code detects a connection timeout condition on an asynchronous / non-blocking session and aborts the connection, pending_call_state remains equal to SSH_PENDING_CALL_CONNECT. As a result, next attempt at calling ssh_connect will skip initialization of session_state to SSH_SESSION_STATE_CONNECTING (client.c:567) due to the earlier jump to pending (client.c:527), which will prevent proper detection of the condition leading to returning SSH_AGAIN (client.c:629) and result in returning SSH_ERROR (client.c:636) instead.

A solution would be to reset pending_call_state to SSH_PENDING_CALL_NONE in ssh_disconnect, possibly just after setting the session_state to SSH_SESSION_STATE_DISCONNECTED (client.c:724)

session->opts.fd = SSH_INVALID_SOCKET;

+ session->pending_call_state=SSH_PENDING_CALL_NONE;

while ((it=ssh_list_get_iterator(session->channels)) != NULL) {

Event Timeline

Jakuje added a project: Restricted Project.Oct 2 2020, 12:42 PM
Jakuje added a subscriber: Jakuje.

Thank you for the report and analysis. It looks reasonable to add this reset to disconnect function, rather than keeping it in invalid state. I submitted the following merge request for review:

sahanaprasad07 edited projects, added Restricted Project; removed Restricted Project.

Fixed in 5348267f for the reference