> From: Felipe Gasper <fel...@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

Reply via email to