< Previous by Date Date Index Next by Date >
< Previous in Thread Thread Index Next in Thread >

Re: [reSIProcate] TCP connection failure


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@xxxxxxxxxxxx> 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@xxxxxxxx>
> 
> Send instant messages to your online friends
> http://au.messenger.yahoo.com 
> _______________________________________________
> resiprocate-devel mailing list
> resiprocate-devel@xxxxxxxxxxxxxxxxxxx
>
https://list.sipfoundry.org/mailman/listinfo/resiprocate-devel
> 


-- Gregory McGarry <g.mcgarry@xxxxxxxx>

Send instant messages to your online friends http://au.messenger.yahoo.com