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, Dec 22, 2019 at 16:47:11 +0000, Sad Clouds wrote:

> 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.

LOL.  Sorry :) I mean, you are already using poll(2).  It literally
cannot get *any* worse.  Literally.  The margins of this email are
just too narrow...  Sorry again, traumatic memories...

E.g. NetBSD and Solaris never report POLLHUP for sockets.  Windows and
OSX report POLLHUP when remote half-closes.  Linux reports it on full
close.  NetBSD and Solaris don't report POLLERR on failed connect(2),
just POLLOUT.  And I don't even want to think about scenarios like
reset after half-close...


> 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?

On NetBSD you always get SIGPIPE (whn not turned off), right?


> 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.

As I said, this is exactly how the unix pipes are supposed to work.
If the reader goes away, the writer gets SIGPIPE.  Not doing that for
sockets would be a huge mistake b/c a program should not care if its
stdout is secretly a socket.

If you want to handle this in your program you turn that default
behavior off with one of the *_NOSIG* flags.  Yes, it's #ifdef'y, but
not that bad.  If SOCK_NOSIGPIPE is defined, use it when you create
the socket.  Otherwise if SO_NOSIGPIPE is defined, set it after socket
is created.  If neither is defined use MSG_NOSIGNAL - probably you can
just always use it if it's defined for good measure and to simplify
the #ifdefs


-uwe


Home | Main Index | Thread Index | Old Index