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

[reSIProcate] TcpTransport patch.


Dear resip devels,
resiprocate 1.9.9

when sip stack has to send outgoing sip message through tcp transport 
TcpBaseTrasnport does next steps:
1) makes lookup for the suitable connection by destination.( 
TcpBaseTransport.cxx:300 )
2) if no connection exists - tcp connection for destination is being created.( 
TcpBaseTransport.cxx:311 )
3) mapping looks like destination => Connection

The problem arrises during next scenario:

1) sip stack sends outgoing sip message trough tcp connection C1, C1 was 
created by TcpBaseTransport, because it was not found. C1 is a Tuple [ V4 
dest_host:5060 TCP ]
2) remote peer does not answer into C1. But it tries to create new incoming 
conection  C2  to this_proxy_host:5060. TcpBaseTransport produces an error 
"TcpBaseTransport.cxx:183:Someone probably sent a reciprocal SYN at us." and 
rejects it.

According to
http://tools.ietf.org/html/rfc3261#section-18.1.1, paragraph 8

==========================================
Under error conditions, the
   server may attempt to open a new connection to send the response.  To
   handle this case, the transport layer MUST also be prepared to
   receive an incoming connection on the source IP address from which
   the request was sent and port number in the "sent-by" field.
==========================================


Could you please consider provided patch, which might resolve described issue?

Sincerely, Taras.
diff -rupN resiprocate-1.9.2.orig/resip/stack/Connection.cxx resiprocate-1.9.2/resip/stack/Connection.cxx
--- resiprocate-1.9.2.orig/resip/stack/Connection.cxx   2015-08-11 13:56:12.427389596 +0000
+++ resiprocate-1.9.2/resip/stack/Connection.cxx        2015-08-11 14:48:28.081926713 +0000
@@ -27,15 +27,16 @@ volatile bool Connection::mEnablePostCon
 #define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT
 
 Connection::Connection(Transport* transport,const Tuple& who, Socket socket,
-                       Compression &compression)
+                       Compression &compression, bool isServer)
    : ConnectionBase(transport,who,compression),
      mRequestPostConnectSocketFuncCall(false),
      mInWritable(false),
      mFlowTimerEnabled(false),
-     mPollItemHandle(0)
+     mPollItemHandle(0),
+     mIsServer( isServer )
 {
    mWho.mFlowKey=(FlowKey)socket;
-   InfoLog (<< "Connection::Connection: new connection created to who: " << mWho);
+   InfoLog (<< "Connection::Connection: new connection created to who: " << mWho << ", is server = " << mIsServer);
 
    if(transport && isWebSocket(transport->transport()))
    {
@@ -477,6 +478,8 @@ Connection::processPollEvent(FdPollEvent
    }
 }
 
+bool Connection::isServer()const{ return mIsServer; }
+
 /* ====================================================================
  * The Vovida Software License, Version 1.0 
  * 
diff -rupN resiprocate-1.9.2.orig/resip/stack/Connection.hxx resiprocate-1.9.2/resip/stack/Connection.hxx
--- resiprocate-1.9.2.orig/resip/stack/Connection.hxx   2015-08-11 13:56:12.435390689 +0000
+++ resiprocate-1.9.2/resip/stack/Connection.hxx        2015-08-11 14:43:03.970653125 +0000
@@ -43,7 +43,7 @@ class Connection : public ConnectionBase
       friend EncodeStream& operator<<(EncodeStream& strm, const resip::Connection& c);
 
    public:
-      Connection(Transport* transport,const Tuple& who, Socket socket, Compression &compression);
+      Connection(Transport* transport,const Tuple& who, Socket socket, Compression &compression, bool isServer);
       virtual ~Connection();
       
       /*!
@@ -103,6 +103,7 @@ class Connection : public ConnectionBase
       static volatile bool mEnablePostConnectSocketFuncCall;
       static void setEnablePostConnectSocketFuncCall(bool enabled = true) { mEnablePostConnectSocketFuncCall = enabled; }
 
+      bool isServer()const;
    protected:
       /// pure virtual, but need concrete Connection for book-ends of lists
       virtual int read(char* /* buffer */, const int /* count */) { return 0; }
@@ -127,6 +128,7 @@ class Connection : public ConnectionBase
       /// no value semantics
       Connection(const Connection&);
       Connection& operator=(const Connection&);
+      bool mIsServer;
 };
 
 EncodeStream& 

diff -rupN resiprocate-1.9.2.orig/resip/stack/ConnectionManager.cxx resiprocate-1.9.2/resip/stack/ConnectionManager.cxx
--- resiprocate-1.9.2.orig/resip/stack/ConnectionManager.cxx    2015-08-11 13:56:12.423389048 +0000
+++ resiprocate-1.9.2/resip/stack/ConnectionManager.cxx 2015-08-11 14:51:18.699221980 +0000
@@ -24,7 +24,7 @@ UInt64 ConnectionManager::MinimumGcHeadr
 bool ConnectionManager::EnableAgressiveGc = false;
 
 ConnectionManager::ConnectionManager() : 
-   mHead(0,Tuple(),0,Compression::Disabled),
+   mHead(0,Tuple(),0,Compression::Disabled, false),
    mWriteHead(ConnectionWriteList::makeList(&mHead)),
    mReadHead(ConnectionReadList::makeList(&mHead)),
    mLRUHead(ConnectionLruList::makeList(&mHead)),
@@ -215,7 +215,7 @@ ConnectionManager::addConnection(Connect
 void
 ConnectionManager::removeConnection(Connection* connection)
 {
-   //DebugLog (<< "ConnectionManager::removeConnection()");
+   DebugLog (<< "ConnectionManager::removeConnection() " << *connection );
 
    mIdMap.erase(connection->mWho.mFlowKey);
    mAddrMap.erase(connection->mWho);


diff -rupN resiprocate-1.9.2.orig/resip/stack/TcpBaseTransport.cxx resiprocate-1.9.2/resip/stack/TcpBaseTransport.cxx
--- resiprocate-1.9.2.orig/resip/stack/TcpBaseTransport.cxx     2015-08-11 13:56:12.433390415 +0000
+++ resiprocate-1.9.2/resip/stack/TcpBaseTransport.cxx  2015-08-11 14:45:49.663286045 +0000
@@ -174,11 +174,18 @@ TcpBaseTransport::processListen()
          mSocketFunc(sock, transport(), __FILE__, __LINE__);
       }
 
-      if(!mConnectionManager.findConnection(tuple))
+      Connection* c = mConnectionManager.findConnection(tuple);
+      if(!c)
       {
          createConnection(tuple, sock, true);
       }
-      else
+      else if( false == c->isServer() )
+      {
+         DebugLog( << "Have client connection for " << tuple << ", but got server one" );
+         delete c;
+         createConnection(tuple, sock, true);
+      }
+      else 
       {
          InfoLog(<<"Someone probably sent a reciprocal SYN at us.");


diff -rupN resiprocate-1.9.2.orig/resip/stack/TcpConnection.cxx resiprocate-1.9.2/resip/stack/TcpConnection.cxx
--- resiprocate-1.9.2.orig/resip/stack/TcpConnection.cxx        2015-08-11 13:56:12.435390689 +0000
+++ resiprocate-1.9.2/resip/stack/TcpConnection.cxx     2015-08-11 14:47:24.344219711 +0000
@@ -12,8 +12,8 @@ using namespace resip;
 #define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT
 
 TcpConnection::TcpConnection(Transport* transport,const Tuple& who, Socket fd,
-                             Compression &compression) 
-  : Connection(transport,who, fd, compression)
+                             Compression &compression, bool isServer) 
+  : Connection(transport,who, fd, compression, isServer)
 {
    DebugLog (<< "Creating TCP connection " << who << " on " << fd);
 }

diff -rupN resiprocate-1.9.2.orig/resip/stack/TcpConnection.hxx resiprocate-1.9.2/resip/stack/TcpConnection.hxx
--- resiprocate-1.9.2.orig/resip/stack/TcpConnection.hxx        2015-08-11 13:56:12.425389322 +0000
+++ resiprocate-1.9.2/resip/stack/TcpConnection.hxx     2015-08-11 14:47:07.823962968 +0000
@@ -11,7 +11,7 @@ class Tuple;
 class TcpConnection : public Connection
 {
    public:
-      TcpConnection( Transport* transport, const Tuple& who, Socket fd, Compression &compression);
+      TcpConnection( Transport* transport, const Tuple& who, Socket fd, Compression &compression, bool isServer);
       
       int read( char* buf, const int count );
       int write( const char* buf, const int count );


diff -rupN resiprocate-1.9.2.orig/resip/stack/TcpTransport.cxx resiprocate-1.9.2/resip/stack/TcpTransport.cxx
--- resiprocate-1.9.2.orig/resip/stack/TcpTransport.cxx 2015-08-11 13:56:12.427389596 +0000
+++ resiprocate-1.9.2/resip/stack/TcpTransport.cxx      2015-08-11 14:47:38.088097202 +0000
@@ -42,7 +42,7 @@ Connection*
 TcpTransport::createConnection(const Tuple& who, Socket fd, bool server)
 {
    assert(this);
-   Connection* conn = new TcpConnection(this,who, fd, mCompression);
+   Connection* conn = new TcpConnection(this,who, fd, mCompression, server);
    return conn;
 }

diff -rupN resiprocate-1.9.2.orig/resip/stack/WsTransport.cxx resiprocate-1.9.2/resip/stack/WsTransport.cxx
--- resiprocate-1.9.2.orig/resip/stack/WsTransport.cxx  2015-08-11 13:56:12.437390963 +0000
+++ resiprocate-1.9.2/resip/stack/WsTransport.cxx       2015-08-11 14:49:39.131632815 +0000
@@ -45,7 +45,7 @@ Connection*
 WsTransport::createConnection(const Tuple& who, Socket fd, bool server)
 {
    assert(this);
-   Connection* conn = new WsConnection(this,who, fd, mCompression, mConnectionValidator);
+   Connection* conn = new WsConnection(this,who, fd, mCompression, mConnectionValidator, server);
    return conn;
 }

diff -rupN resiprocate-1.9.2.orig/resip/stack/WsConnection.cxx resiprocate-1.9.2/resip/stack/WsConnection.cxx
--- resiprocate-1.9.2.orig/resip/stack/WsConnection.cxx 2015-08-11 13:56:12.423389048 +0000
+++ resiprocate-1.9.2/resip/stack/WsConnection.cxx      2015-08-11 14:49:06.329151634 +0000
@@ -11,8 +11,8 @@ using namespace resip;
 WsConnection::WsConnection(Transport* transport,
                            const Tuple& who, Socket fd,
                            Compression &compression,
-                           SharedPtr<WsConnectionValidator> wsConnectionValidator)
-  : TcpConnection(transport,who, fd, compression), WsConnectionBase(wsConnectionValidator)
+                           SharedPtr<WsConnectionValidator> wsConnectionValidator, bool isServer)
+  : TcpConnection(transport,who, fd, compression, isServer), WsConnectionBase(wsConnectionValidator)
 {
    DebugLog (<< "Creating WS connection " << who << " on " << fd);
 }

diff -rupN resiprocate-1.9.2.orig/resip/stack/WsConnection.hxx resiprocate-1.9.2/resip/stack/WsConnection.hxx
--- resiprocate-1.9.2.orig/resip/stack/WsConnection.hxx 2015-08-11 13:56:12.432390279 +0000
+++ resiprocate-1.9.2/resip/stack/WsConnection.hxx      2015-08-11 14:49:20.009020448 +0000
@@ -18,7 +18,7 @@ class WsConnection :  public TcpConnecti
       WsConnection(Transport* transport,
                    const Tuple& who, Socket fd,
                    Compression &compression,
-                   SharedPtr<WsConnectionValidator> wsConnectionValidator);
+                   SharedPtr<WsConnectionValidator> wsConnectionValidator, bool isServer);
 
diff -rupN resiprocate-1.9.2.orig/resip/stack/ssl/TlsConnection.cxx resiprocate-1.9.2/resip/stack/ssl/TlsConnection.cxx
--- resiprocate-1.9.2.orig/resip/stack/ssl/TlsConnection.cxx    2015-08-11 13:56:12.432390279 +0000
+++ resiprocate-1.9.2/resip/stack/ssl/TlsConnection.cxx 2015-08-11 14:50:11.556062402 +0000
@@ -29,7 +29,7 @@ TlsConnection::TlsConnection( Transport*
                               Socket fd, Security* security, 
                               bool server, Data domain,  SecurityTypes::SSLType sslType ,
                               Compression &compression) :
-   Connection(transport,tuple, fd, compression),
+   Connection(transport,tuple, fd, compression, server),
    mServer(server),
    mSecurity(security),
    mSslType( sslType ),