/ curl Public
SSH: Fix incorrect timeout failures on disconnects. #1479
Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge.
libcurl is leaking memory when using sftp and a timeout. This was first reported on the mailing list.
The memory leak reported on the mailing list is a symptom of a larger problem - SSH sessions are not freed when a timeout is used. I suspect this problem is also present on other platforms, but may not manifest itself as a memory leak on all platforms.
I used the Visual Studio memory analysis tools to find that libssh2 is leaking some WinCNG structs for each connection. This is because libcurl is never calling the
libssh2_session_freefunction when a timeout is set. Without a timeout, the function is called and things get cleaned up correctly.
In a disconnect situation, the
close_all_connectionsfunction replaces the easy handle associated with a connection with a 'closure handle'. This will reset all progress values associated with the connection to zero values. As a result, calculations using these values will return incorrect values.
close_all_connectionsfunction eventually calls into the
sftp_disconnectfunction, which runs the
ssh_block_statemachfunction. In this function, if a timeout is set, the "time left" value will always be negative, because the start time has been reset to zero. This means that if a timeout is set, disconnections always fail with a timeout error, rather than finish successfully. Since the easy handle has been replaced with the closure handle, this timeout error will not be reported, regardless of the verbose setting used on the original easy handle.