> 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

Reply via email to