-
-
Notifications
You must be signed in to change notification settings - Fork 393
Description
We have an awkward thing in our stream abstraction: there's the abstract Stream interface, and then there's the abstract HalfCloseableStream interface, which is just Stream with an added send_eof method.
In practice, every single Stream you'd ever meet in real life – TCP connections, StapledStream, SSH tunnels, HTTP/2 streams, etc. etc. etc. – is a HalfCloseableStream. Except... SSLStream, because for some reason TLS doesn't support half-close. And unfortunately TLS is super important in practice, so even though in some abstract sense it's TLS that's broken and fails to implement a proper byte stream, we instead broke our Stream interface to accomodate TLS.
BUT! It turns out that TLS 1.3 fixed this! Quoting RFC 8446 §6.1:
Each party MUST send a "close_notify" alert before closing its write side of the connection, unless it has already sent some error alert. This does not have any effect on its read side of the connection. Note that this is a change from versions of TLS prior to TLS 1.3 in which implementations were required to react to a "close_notify" by discarding pending writes and sending an immediate "close_notify" alert of their own. That previous requirement could cause truncation in the read side. Both parties need not wait to receive a "close_notify" alert before closing their read side of the connection, though doing so would introduce the possibility of truncation.
OpenSSL has supported that [= half-close] for a very long time, even when the older TLS standards didn't say that was supported.
So TLS 1.3 now has the same semantics as every other common byte-stream transport, and apparently in some cases we can get that with earlier versions too, if we cross our fingers and the moon is full.
I was already on the fence about whether we should have two separate types for Stream and HalfCloseableStream, versus merging them into a single type and just saying that send_eof might fail in some cases. This clearly tips things over, given that it means SSLStream is going to want to implement send_eof.
We'll still have to document clearly that (a) send_eof may not work in all cases, and (b) even if it works, there's lots of software out there that doesn't really understand half-close. But at least we can drop HalfCloseableStream. I never liked that thing.