> From: openssl-users <openssl-users-boun...@openssl.org> On Behalf Of Felipe
> Gasper
> Sent: Wednesday, 26 October, 2022 11:15
> 
>       I’m seeing that OpenSSL 3, when it reads empty on a socket, sends some
> sort of response, e.g.:
> 
> ----- before read
> [pid 42417] read(7<UNIX:[276782->276781]>, "", 5) = 0
> [pid 42417] sendmsg(7<UNIX:[276782->276781]>, {msg_name=NULL, msg_namelen=0,
> msg_iov=[{iov_base="\0022", iov_len=2}], msg_iovlen=1,
> msg_control=[{cmsg_len=17, cmsg_level=SOL_TLS, cmsg_type=0x1}],
> msg_controllen=17, msg_flags=0}, 0) = -1 EPIPE (Broken pipe)
> ----- after read
> 
>       What is that being sent after the read()? Is there a way to disable
> it?

I'd guess it's a TLS Alert Close_notify.

When read/recv on a TCP stream socket returns 0, it means a TCP FIN has been 
received from the peer (or possibly some interfering middleman, such as a 
firewall). This indicates the peer will no longer be sending any application 
data, only at most ACKs and perhaps a RST if conversation does not go quietly 
into that good night. Since TLS requires bidirectional communications, that 
means the TLS conversation is effectively open, and the local end needs to be 
closed; and TLS requires sending a close_notify so the peer knows the 
conversation has not been truncated.

Now, the most common cause of a FIN is the peer calling close(), which means it 
can't receive that close_notify. But TCP supports half-close, and the peer 
*could have* called shutdown(, SD_SEND), indicating that it was done sending 
but still wanted to be able to receive data. So the local side has no way of 
knowing, at the point where it gets a 0 from read(), that the peer definitely 
can't see the close_notify; and thus it's still obligated by the TLS 
specification (I believe) to send it.

At any rate, that's my understanding of the requirement for sending 
close_notify - I haven't confirmed that in the RFC - and what I suspect OpenSSL 
is doing there. I could well be wrong.

If the peer *has* called close, then EPIPE is what you'd expect. Note that on 
UNIXy systems this means you should have set the disposition of SIGPIPE to 
SIG_IGN to avoid being signaled, but all well-written UNIX programs should do 
that anyway. (SIGPIPE, as Dennis Ritchie noted many years ago, was always 
intended as a failsafe for poorly-written programs that fail to check for 
errors when writing.)

-- 
Michael Wojcik

Reply via email to