[openssl-users] Close TCP socket after SSL_clear()?

Michael Wojcik Michael.Wojcik at microfocus.com
Fri Jan 11 20:48:01 UTC 2019

> From: openssl-users [mailto:openssl-users-bounces at openssl.org] On Behalf Of Karl Denninger
> Sent: Friday, January 11, 2019 13:04

>    if (!SSL_shutdown(connection)) {
>        SSL_shutdown(connection)
>    }

Or if you really want to baffle future maintainers:

        SSL_shutdown(connection) || SSL_shutdown(connection);

> The underlying handle is still open at the OS level after this, so on Unix anyway you want
> to notify the OS that the socket is invalid for further I/O and then close it.
> ...
>                    shutdown(slave_socket[x].fd, SHUT_RDWR);
>                    close(slave_socket[x].fd);

Maybe I'm missing something, but I don't see much advantage to calling shutdown(SHUT_RDRW) and then immediately calling close(). close will implicitly do what shutdown does, in the normal case, including trying to send unsent data and waiting (for a while) for any remaining ACKs.

If there's unsent or un-ACK'd data, shutdown will attempt to send it until the TCP retransmit limit is reached; that's normally longer than the linger time for the socket, so shutdown could try harder, and by the same token block longer, than close. But the same effect can be achieved by setting a longer linger time for the socket and just calling close.

Similarly, if linger has been disabled (by setting the SO_LINGER option appropriately), then close will just abort the connection (i.e. send an RST, rather than a FIN, and not wait for the corresponding FIN-ACK; or if the peer sent the FIN, send an RST rather than a FIN-ACK and not wait for the last ACK). But anyone who disables linger on a TLS connection gets what they deserve.

shutdown is generally useful if:

- You only want a half-close (which is rarely used, even when it would be useful, and isn't generally appropriate for a TLS connection).

- You want a full close, but you want to be able to retrieve the error information from the socket if the close fails. In that case, use shutdown, followed by getsockopt(SO_ERROR) if shutdown returns an error, followed by close. But your code is ignoring the return value from shutdown and not using getsockopt(SO_ERROR).

The real question is: will the application do anything differently if any remaining outbound data - which there shouldn't be because at this point we've tried to do a blocking SSL_shutdown - can't be sent, and the closing FIN / FIN-ACK / ACK handshake completed, within the default linger time? And if so, will the application do anything that can't be achieved by just increasing the linger time?

I think it'd be nice if more non-trivial applications used shutdown(SHUT_RDWR) + getsockopt(SO_ERROR) + close, and reported the error (if there is one) for diagnostic purposes. But beyond that there isn't a lot most applications can do, and for most a simple close is probably going to be fine.

But as I said I may have overlooked some good reason for this particular code pattern.

Michael Wojcik
Distinguished Engineer, Micro Focus

More information about the openssl-users mailing list