[reSIProcate] TCP connection failure

Jason Fischl jason at counterpath.com
Sun Jun 11 13:50:32 CDT 2006


In the case of the signal call, it would be better if this were done in the
application before any threads get started. For example, in
main/repro/repro.cxx, you will see the call to ignore the SIGPIPE signal. Is
this not sufficient to remove the problem? I don't think any changes are
required in the stack itself unless I am missing a particular o/s specific
case.


On 6/10/06, Gregory McGarry <gregorymcgarry at yahoo.com.au> wrote:
>
> And this is the fix.  Is there any particular reason why
> write() is used in preference to send() on non-win32
> platforms?  Otherwise, I'll just use send() all the time.
>
> Any problems here?
>
> Index: TcpConnection.cxx
> ===================================================================
> --- TcpConnection.cxx   (revision 6360)
> +++ TcpConnection.cxx   (working copy)
> @@ -85,6 +85,8 @@
>
> #if defined(WIN32)
>     int bytesWritten = ::send(mSocket, buf, count, 0);
> +#elif defined(MSG_NOSIGNAL)
> +   int bytesWritten = ::send(mSocket, buf, count,
> MSG_NOSIGNAL);
> #else
>     int bytesWritten = ::write(mSocket, buf, count);
> #endif
> Index: TcpBaseTransport.cxx
> ===================================================================
> --- TcpBaseTransport.cxx        (revision 6360)
> +++ TcpBaseTransport.cxx        (working copy)
> @@ -2,6 +2,10 @@
> #include "resip/stack/config.hxx"
> #endif
>
> +#if !defined(OS_NOSIGPIPE) && !defined(MSG_NOSIGNAL)
> +#include <signal.h>
> +#endif
> +
> #include <memory>
> #include "rutil/compat.hxx"
> #include "rutil/Data.hxx"
> @@ -210,6 +214,12 @@
>
>           DebugLog (<<"Opening new connection to " <<
> data->destination);
>           makeSocketNonBlocking(sock);
> +#if defined(SO_NOSIGPIPE)
> +         int on = 1;
> +         ::setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, &on,
> sizeof(on));
> +#elif !defined(WIN32) && !defined(MSG_NOSIGNAL)
> +         ::signal(SIGPIPE, SIG_IGN);
> +#endif
>           int e = connect( sock, &servaddr,
> data->destination.length() );
>
>           // See Chapter 15.3 of Stevens, Unix Network
> Programming Vol. 1 2nd Edition
>
> --- Gregory McGarry <gregorymcgarry at yahoo.com.au> wrote:
>
> > AFAICT, there are two failure paths in the TCP code in
> > TcpBaseTransport::processSomeWries().  Windows returns a
> > socket exception when a write to a failed connection is
> > performed.  The Connection is deleted and falls back to
> > the
> > UDP transport.
> >
> > OS X and NetBSD don't return a socket exception and
> > Connection::performWrite() is expected to recognise the
> > missing connection.  Rather, it crashes on write() or
> > somewhat later in select().
> >
> > I haven't found a solution to the problem yet.
> >
> > It is easy to reproduce.  Try basicRegister (without the
> > outbound proxy line in the code) and attempt to register
> > to
> > a proxy with a TCP SRV entry but without TCP support.
> >
> > Alternatively, here's a unit test to demonstrate the
> > problem:
> >
> > #include <stdio.h>
> > #include <assert.h>
> > #include <errno.h>
> > #include <fcntl.h>
> > #include <unistd.h>
> > #include <sys/socket.h>
> > #include <sys/select.h>
> > #include <netinet/in.h>
> >
> > int
> > main()
> > {
> >         int sock = socket(AF_INET, SOCK_STREAM, 0);
> >         assert(sock > 0);
> >
> >         int flags = fcntl(sock, F_GETFL, 0);
> >         int err = fcntl(sock, F_SETFL, flags | O_NONBLOCK
> > );
> >         assert(err == 0);
> >
> >         struct sockaddr_in servAddr;
> >         memset(&servAddr, 0, sizeof(struct sockaddr_in));
> >         servAddr.sin_family = AF_INET;
> >         servAddr.sin_addr.s_addr = htonl(0xc0a80080);
> >         servAddr.sin_port = htons(5060);
> >
> >         err = connect(sock, (struct sockaddr*)&servAddr,
> > sizeof(struct sockaddr_in));
> >         if (err < 0)
> >                 printf("error %d: %s\n", err,
> > strerror(errno));
> >
> >         fd_set wfds;
> >         fd_set efds;
> >         FD_ZERO(&wfds);
> >         FD_ZERO(&efds);
> >         FD_SET(sock, &wfds);
> >         FD_SET(sock, &efds);
> >
> >         err = select(sock+1, NULL, &wfds, &efds, NULL);
> >         if (err < 0)
> >                 printf("select failed\n");
> >
> >         if (FD_ISSET(sock, &wfds))
> >                 printf("write set\n");
> >         if (FD_ISSET(sock, &efds))
> >                 printf("exception set\n");
> >
> >         char buffer[] = "hello";
> >         int n = write(sock, buffer, strlen(buffer));
> >         printf("n == %d\n", n);
> >
> >         return 0;
> > }
> >
> >
> >
> > -- Gregory McGarry <g.mcgarry at ieee.org>
> >
> > Send instant messages to your online friends
> > http://au.messenger.yahoo.com
> > _______________________________________________
> > resiprocate-devel mailing list
> > resiprocate-devel at list.sipfoundry.org
> >
> https://list.sipfoundry.org/mailman/listinfo/resiprocate-devel
> >
>
>
> -- Gregory McGarry <g.mcgarry at ieee.org>
>
> Send instant messages to your online friends http://au.messenger.yahoo.com
> _______________________________________________
> resiprocate-devel mailing list
> resiprocate-devel at list.sipfoundry.org
> https://list.sipfoundry.org/mailman/listinfo/resiprocate-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://list.resiprocate.org/pipermail/resiprocate-devel/attachments/20060611/40f85074/attachment.htm>


More information about the resiprocate-devel mailing list