Does anyone have a straightforward example of the canonical way to handle SSL_shutdown() in OpenSSL 1.1.1? I mean both when my code is the initiator of the shutdown and also when I'm the peer, and also for both blocking and non-blocking BIOs? I've read and re-read the SSL_shutdown() man page and it seems to me that there's a lot of conflicting content there. It says you can call SSL_shutdown() twice, and it also says "However, it is recommended to wait for it using SSL_read() instead". It says "It is not possible to call SSL_write() after calling SSL_shutdown()", but it also says that for non-blocking BIOs, we might get an SSL_ERROR_WANT_WRITE and the calling process "must take appropriate action to satisfy the needs of SSL_shutdown()"... what "appropriate action" is is not clearly specified but I assume it means invoke SSL_write(). Under RETURN VALUES <0 it says the shutdown was not successful, but then says we can get this if an action is needed to continue the operation for non-blocking BIOs... by "continue the operation" does that mean call SSL_read() again? If so what's the difference in behavior of my code between SSL_shutdown() returning 0 or <0? I just wish the docs would say what the recommended best practices are in a clear way, rather than offering lots of not-very-clear alternatives, or that there was example code somewhere of how the OpenSSL devs designed this to be handled. Also as a separate question, if I'm always going to be closing my socket once the shutdown is complete is there any advantage in worrying about bi-directional shutdown, versus simply calling SSL_shutdown(), ignoring the return value, and closing the socket? I would like my code to be a good neighbor and play nicely with others but if it doesn't matter I guess I could side-step all the above confusion and simply get out. Let me also assume that the peer may not be reading the socket constantly. For example suppose the peer is an interactive shell of some kind and it's sitting at a prompt waiting for user input and not invoking SSL_read() etc. Is it possible to ever complete a bi- directional handshake shutdown with that peer anyway? If we need to wait for it to reply I don't see how.