> On Oct 26, 2022, at 13:34, Michael Wojcik via openssl-users
> <openssl-users@openssl.org> wrote:
>
>> 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.)
I wouldn’t normally expect EPIPE from a read operation. I get why it happens;
it just seems odd. Given that it’s legitimate for a TLS peer to send the
close_notify and then immediately do TCP close, it also seems like EPIPE is a
“fact of life” here.
-FG