NetBSD-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: ECONNRESET not returned when calling send() on a socket



On Sun, 22 Dec 2019 16:10:15 +0300
Valery Ushakov <uwe%stderr.spb.ru@localhost> wrote:

> Of course since you are writing a networking server you DO want to be
> notifed about send() errors and SIGPIPE gets in the way.  So you can
> tell the kernel, "hey, I know what I'm doing, I will handle this
> myself".  I don't remember off hand which OS has which of these flags,
> but there're
> 
>   SOCK_NOSIGPIPE - can be or-ed into the type argument of socket(2)
>   SO_NOSIGPIPE   - SOL_SOCKET level socket option
>   MSG_NOSIGNAL   - send(2) flag
> 

This is the problem, I'm trying to deal with various idiosyncrasies of
sockets APIs. In order for the code to be portable and behave
correctly across various platforms, you need to be aware of such
issues, but it's not always obvious from the man pages. Also different
platforms have different ways of dealing with SIGPIPE, i.e. Linux and
BSD have MSG_NOSIGNAL for send(), Solaris instead has SO_NOSIGPIPE for
setsockopt(), etc. The most portable way seems to be to set a signal
handler to ignore SIGPIPE.

What I don't understand is when the other end of TCP connection sends
RST, performing a send() on a socket sometimes results in ECONNRESET
and sometimes in SIGPIPE. Why?

As I mentioned previously, I was under the impression that SIGPIPE was
sent only after send() returned -1 with errno set to ECONNRESET and you
then call send() again on this socket. But this is not what I was
seeing on NetBSD.

https://stackoverflow.com/questions/33053507/econnreset-in-send-linux-c

Reading comments on stackoverflow, some people state that ECONNRESET is
returned when RST arrived while some of the data from send() was
in-flight and might have been lost. And SIGPIPE is sent when RST
arrived while all of the previously sent data was acknowledged by TCP
and there was no data loss. I'm not sure if this is universally true
across all platforms or not.

The whole idea of SIGPIPE for sockets seems like huge mistake and just
adds to confusion and potential to introducing bugs which terminate
your process when this signal is not handled. But, this is ancient
history and that is how Unix was designed. I just wanted to understand
ECONNRESET vs SIGPIPE for send() syscall.



Home | Main Index | Thread Index | Old Index