Following up to see if anyone is willing to share their thoughts on any of these questions. Even a partial answer would be helpful to know whether I am thinking about this correctly.
Thank you -Evan On Tue, Jan 11, 2022 at 10:55 PM Evan M <etm2...@columbia.edu> wrote: > Hi all - apologies for the long email.. I want to make sure I'm explaining > things clearly. > > I am working on a wrapper over libssh2 for the Rust programming language. > Rust has RAII similar to C++ where resources for a struct / object are > released when the struct is dropped (i.e. goes out of scope). Since > destructors run in a single shot and should ideally be non-blocking, we > need a way to release session resources without performing blocking IO (or > any IO at all). This is especially important when using libssh2 in a > non-blocking async context. > > My question has two parts. First, I want to make sure I understand the > correct way to completely close a session without leaking any memory. I > believe there is some complexity involved since libssh2 mixes SSH protocol > IO with freeing memory in most (maybe all) of the cleanup functions (such > as libssh2_session_free() and libssh2_channel_free()). > > Is this the procedure below the correct way to close a session? For each > of these steps I'm assuming the functions are retried until they succeed in > the case of LIBSSH2_ERROR_EAGAIN or LIBSSH2_ERROR_TIMEOUT being returned. > > 1. Call the appropriate shutdown / free function for any and all objects > associated with the session (i.e. libssh2_sftp_shutdown(), > libssh2_channel_free(), libssh2_channel_forward_cancel(), etc...). These > functions perform IO in addition to freeing memory. > > 2. Call libssh2_session_disconnect() to send the SSH disconnect message > > 3. Call libssh2_session_free(); At this point I believe > libssh2_session_free() should not perform any IO since all channels and > listeners have already been closed. I read through the code and this seems > to be the case, but perhaps I missed something. > > On this last point, I also didn't see any code preventing libssh2 from > sending data to the server after it has sent a disconnect message, even > though the SSH spec states that no further transmissions are permitted. I'm > therefore assuming that if libssh2_session_disconnect() is called before > the channel_free or similar, libssh2 will continue sending messages to the > server in these cleanup functions. It also looks like libssh2_session_free > will cause IO to close channels if they are still open when it is called. > > > Second, I'd like to understand how to clean up in a non-blocking context > where we cannot wait for IO to complete, such as in the destructor for a > struct in our Rust library. Is it alright to call > shutdown() in a UNIX environment to close the socket without recycling the > fd and then call the appropriate free/shutdown/cancel functions before > calling libssh2_session_free()? The thought is that after calling shutdown > on the socket any IO performed by the libssh2 code will fail, which from my > understanding will cause libssh2_session_free() to discard the IO error and > proceed through the routine, freeing the session memory. This allows us to > avoid EAGAIN and timeouts in the destructor at the cost of closing the > socket without cleanly ending the SSH session. > > Thanks! > > - Evan > > -- > Evan Mesterhazy > etm2...@columbia.edu > -- Evan Mesterhazy etm2...@columbia.edu
-- libssh2-devel mailing list libssh2-devel@lists.haxx.se https://lists.haxx.se/listinfo/libssh2-devel