SSL_read empty -> close?

Michael Wojcik Michael.Wojcik at microfocus.com
Thu Nov 3 15:37:43 UTC 2022


> From: Felipe Gasper <felipe at felipegasper.com>
> Sent: Thursday, 3 November, 2022 08:51
> 
> You probably know this, but: On Linux, at least, if a TCP socket close()s
> with a non-empty read buffer, the kernel sends TCP RST to the peer.

Yes, that's a conditional-compliance (SHOULD) requirement from the Host Requirements RFC. See RFC 1122, 4.2.2.13.

> Some
> applications “panic” when they receive the RST and discard data.

Well, applications do a lot of things. Receiving an RST informs the peer that some of the data they sent was not successfully processed by the local application, so treating that as an error condition is not inappropriate.

But generally it's better if the application protocol imposes its own record structure and control information on top of TCP's very basic stream.

> It’s a rare
> issue, but when it does it’s a head-scratcher. To avoid that, it’s necessary
> to shutdown(SHUT_RD) then drain the read buffer before close().

Well, it's not *necessary* to do a half-close. Applications often know when they've received all the data the peer intends to send, thanks to record-delimiting mechanisms in the application protocol.

And your description looks wrong anyway: shutdown(SHUT_RD) has implementation-defined behavior for TCP sockets (because TCP does not announce the read side of half-close to the peer), and on Linux causes blocked receives and subsequent receives to return 0 (according to references -- I have't tested it), which means after shutdown(SHUT_RD) you *can't* drain the receive buffer. shutdown(SHUT_WR) would work, since it sends a FIN, telling the peer you won't be sending any more data, and still allows you to receive.

> So it seems like this *shouldn’t* be obscure, if applications do the
> shutdown/drain thing.

It's obscure in the sense that a great many people trying to use TLS get much more basic things wrong.

More generally, the OpenSSL documentation mostly covers the OpenSSL APIs, and leaves networking up to the OpenSSL consumer to figure out. The OpenSSL wiki covers topics that people have written, and those are going to focus on common questions and areas of particular interest for someone. If the interactions among the OpenSSL API, the TLS protocol (in its various versions), and the shutdown system call haven't historically been a problem for many people, then it's "obscure" in the literal sense of not having 
attracted much notice.

And in practice, the majority of TLS use is with HTTP, and HTTP does a fairly good job of determining when more data is expected, and handling cases where it isn't. An HTTP client that receives a complete response and then attempts to use the conversation for its next request, and gets an RST on that, for example, will just open a new conversation; it doesn't care that the old one was terminated. HTTP servers are simliarly tolerant because interactive user agents in particular cancel requests by closing (or, unfortunately, aborting) the connection all the time.

> I would guess that many don’t and just don’t see the
> RST thing frequently enough to worry about it. Regardless, the documentation
> is already pretty voluminous, so if this doesn’t bite many folks, then hey.

Yes, but wiki articles are always appreciated.

-- 
Michael Wojcik


More information about the openssl-users mailing list