realtimenetprots/sipfw/SIP/ConnectionMgr/src/CSipConnection.cpp
changeset 0 307788aac0a8
child 19 b5e99d8877c7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SIP/ConnectionMgr/src/CSipConnection.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,2080 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Name          : CSipConnection.cpp
+// Part of       : ConnectionMgr
+// Version       : SIP/5.0
+//
+
+
+
+#include "CSipConnection.h"
+#include "CSipConnectionMgr.h"
+#include "SipLogs.h"
+#include "CTransportUdp.h"
+#include "CTransportTcp.h"
+#include "CTransportTls.h"
+#include "CIcmpReceiver.h"
+#include "MTransactionFinder.h"
+#include "CSIPServerResolver.h"
+#include "CTcpListeningPoint.h"
+#include "COutgoingData.h"
+#include "CTcpResSender.h"
+#include "MConnectionStateObserver.h"
+#include "CLocalAddrResolver.h"
+#include "MSigCompController.h"
+#include "SipAssert.h"
+#include "CConnectionContainer.h"
+#include "CNetworkManager.h"
+#include "CStateModel.h"
+#include "CommonConsts.h"
+#include "sipstrings.h"
+#include "sipstrconsts.h"
+#include "TSIPTransportParams.h"
+#include "COwnerSettingsList.h"
+#include "siperr.h"
+#include "NetworkInfo.h"
+#include "sipviaheader.h"
+#include "COutgoingRequestQueue.h"
+#include "sipuri.h"
+#include "uricontainer.h"
+#include "siphostport.h"
+#include "siprouteheader.h"
+#include "sipaddress.h"
+#include <uriutils.h>
+using namespace CommsDat;
+
+// Max length for an IP address string representation
+// (The format is either "d.d.d.d" or "h:h:h:h:h:h:h:h"
+//  depending on the address family, where "d" is an 8-bit decimal number
+//  and "h" is a 16-bit hexadecimal number. )
+const TUint KMaxAddressLength( 50 );
+
+const TInt CTransportBase::iOffset = _FOFF( CTransportBase, iLink );
+
+// -----------------------------------------------------------------------------
+// CSipConnection::NewLC
+// -----------------------------------------------------------------------------
+//
+CSipConnection* CSipConnection::NewLC(
+								MTransactionFinder& aFinder,
+								MServerTaFactory& aTaFactory,
+								MTimerManager& aTimer,
+								TUint aTOne,
+								const TSIPTransportParams& aParams,
+								RSocketServ& aServer,
+								MSigCompController& aSigCompHandler,
+								MConnectionStateObserver& aTUNetStatusObserver,
+								CNetworkManager& aNetworkManager,
+								MSipConnectionOwner& aOwner,
+								CNetworkInfo& aNetworkInfo,
+								CSIPNATTraversalController& aNATTraversal )
+	{
+	CSipConnection* self =
+		new( ELeave ) CSipConnection( aFinder, aTaFactory, aTimer, aTOne,
+									  aParams, aServer, aSigCompHandler,
+									  aTUNetStatusObserver, aNetworkManager,
+									  aOwner, aNetworkInfo, aNATTraversal );
+	CleanupStack::PushL( self );
+	self->ConstructL();
+	return self;
+
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::SetOptL
+// -----------------------------------------------------------------------------
+//	
+void CSipConnection::SetOptL( 
+    const TSIPTransportParams& aParams,
+    TUint aOptionName,
+	TUint aOptionLevel,
+	const TDesC8& aOption )
+    {	
+    // Remember opt, it will be used when this caller is using sockets
+    iSettingsList->AddSettingsL( aParams, aOptionName, aOptionLevel, aOption );
+    }
+
+// -----------------------------------------------------------------------------
+// CSipConnection::SetOptL
+// -----------------------------------------------------------------------------
+//		         	                         
+void CSipConnection::SetOptL( 
+    const TSIPTransportParams& aParams,
+    TUint aOptionName,
+	TUint aOptionLevel,
+	TInt aOption )
+    {
+    // Remember opt, it will be used when this caller is using sockets
+    iSettingsList->AddSettingsL( aParams, aOptionName, aOptionLevel, aOption );
+    }
+	
+// -----------------------------------------------------------------------------
+// CSipConnection::SendL
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::SendL( 
+    const TSIPTransportParams& aParams,
+    CSIPResponse& aResponse,
+	TTransactionId aId,
+	TRequestStatus& aStatus )
+	{
+	__SIP_MESSAGE_LOG( "Connection Manager::SendL", aResponse )
+	iStateModel->SendL( aParams, aResponse, aId, aStatus );
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::SendL
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::SendL( 
+    const TSIPTransportParams& aParams,
+    CSIPRequest& aRequest,
+    TBool aForceUDP,
+    const CUri8* aOutboundProxy,
+	const TInetAddr& aRemoteAddr,
+	TRequestStatus& aStatus )
+	{
+	__SIP_MESSAGE_LOG( "Connection Manager::SendL", aRequest )
+	if ( aRemoteAddr.IsMulticast() )
+		{
+		TRequestStatus* status = &aStatus;
+		User::RequestComplete( status, KErrNotSupported );
+		}
+	else
+		{
+		iStateModel->SendL( aParams, 
+		                    aRequest, 
+		                    aForceUDP,
+		                    aOutboundProxy, 
+		                    aRemoteAddr, 
+		                    aStatus );
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::CancelSend
+// -----------------------------------------------------------------------------
+//
+TInt CSipConnection::CancelSend( TRequestStatus &aStatus )
+	{
+	TBool cancelled = EFalse;
+	CTransportBase* listItem = 0;
+	iListIter.SetToFirst();
+	while ( ( listItem = iListIter++ ) != 0 )
+		{
+		cancelled = listItem->CancelSend( aStatus );
+		if(cancelled)
+			{
+			return KErrNone;
+			}
+		}
+
+	CTcpResponseSender* listsender( NULL );
+	iTcpSenderListIter.SetToFirst();
+	while ( ( listsender = iTcpSenderListIter++ ) != 0 )
+		{
+		if ( listsender->CancelSend( aStatus ) )
+			{
+			return KErrNone;
+			}
+		}
+		
+    if ( iRequestQueue )
+        {
+        if ( iRequestQueue->CancelSend( aStatus ) )
+            {
+            return KErrNone;
+            }
+        }
+	return KErrNotFound;
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::CancelResponseSend
+// -----------------------------------------------------------------------------
+//
+TInt CSipConnection::CancelResponseSend( 
+    TTransactionId aId, 
+    TBool aCancelAlso2xxResponses )
+	{
+	TBool cancelled = EFalse;
+	CTransportBase* listItem = 0;
+	iListIter.SetToFirst();
+	while ( ( listItem = iListIter++ ) != 0 )
+		{
+		cancelled = listItem->CancelResponseSend( aId, aCancelAlso2xxResponses );
+		if ( cancelled )
+			{
+			return KErrNone;
+			}
+		}
+	return KErrNotFound;
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::TcpDisconnect
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::TcpDisconnect( 
+    const TSIPTransportParams& aParams,
+    const TInetAddr& aRemoteAddress )
+	{
+	CTransportBase* listItem = 0;
+	iListIter.SetToFirst();
+
+	while ( ( listItem = iListIter++ ) != 0 )
+		{
+		if ( listItem->HasRemoteHost( aParams, 
+		                              aRemoteAddress, 
+		                              SIPStrings::StringF(SipStrConsts::ETCP) ) )
+			{
+			listItem->Disconnect( aRemoteAddress );
+			}
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::FreeResources
+// -----------------------------------------------------------------------------
+//	
+void CSipConnection::FreeResources( 
+    MSIPNATBindingObserver& aSIPNATBindingObserver )
+    {
+    if ( iRequestQueue )
+        {
+        iRequestQueue->FreeResources( aSIPNATBindingObserver );
+        }
+    
+    // Remove all matching persistent transports    
+    CTransportBase* listItem;
+    iListIter.SetToFirst();
+    while ( ( listItem = iListIter++ ) != 0 )
+        {   
+        if ( listItem->Remove( aSIPNATBindingObserver ) )
+            {
+            RemoveTransport( listItem );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSipConnection::SendToTransportL
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::SendToTransportL(
+    const TSIPTransportParams& aParams,
+    CSIPResponse& aResponse,
+	TTransactionId aId,
+	TRequestStatus &aStatus )
+	{
+	CTransportBase* transport = 0;
+
+	CSIPViaHeader* viaHeader = TopViaHeader( &aResponse );
+	if ( viaHeader )
+	{
+		TBool isPortPresent = viaHeader->SentByHostPort().HasPort();
+		if (isPortPresent)
+		{
+			TUint sentByPort = viaHeader->SentByHostPort().Port();
+			if ((sentByPort > KMaxPortValue) || (sentByPort < KMinPortValue))
+			{
+				TRequestStatus* status = &aStatus;
+		    	__SIP_LOG( "Sent-by port is topmost viaheader is invalid, dropping response" )
+		    	User::RequestComplete( status, CSipConnectionMgr::EPortUnreachable );
+		    	return;
+			}
+		}
+	}
+	
+	TBool isTransportUdp = IsTransportUdp( &aResponse );
+
+    transport = FindTransportL( aParams, &aResponse, aId, !isTransportUdp );
+
+    if ( !isTransportUdp && !transport )
+		{
+		// When connected transport is used, there might be several connections
+    	// with same remote address, in that case we had to search through all
+    	// transports for matching the ta id. At this point any matching
+    	// transport wasn't found, now we can take also remote address in count.
+		transport = FindTransportL( aParams, &aResponse, aId, EFalse );
+		
+		if ( !transport )
+		    {
+    		// If there's saved settings regarding remote address, use them 
+    		// instead of address passed from upper layers (probably only the
+    		// port differs)
+    		TInetAddr addrFromResponse;
+            const TInetAddr* address;
+            const TInetAddr* savedAddr = 
+                iSettingsList->SavedRemoteAddr( aParams.TransportId() );
+            if ( savedAddr )
+                {
+                address = savedAddr;
+                }
+            else
+                {
+    			CTransportBase* listItem;
+    			if ( !iList.IsEmpty() )
+    				{
+    				iListIter.SetToFirst();
+    				listItem = iListIter;
+    				listItem->GetAddrFromResponseL( aParams, 
+    				                                aResponse, 
+    				                                addrFromResponse );
+    				}
+                address = &addrFromResponse;
+                }    
+    		
+    		if ( !address->IsWildAddr() )
+    			{
+        		CreateConnectedTransportPointL( aParams, aResponse, *address );
+        		transport = FindTransportL( aParams, &aResponse, aId, EFalse );
+    			}
+    		}
+		}
+	
+	if ( transport )
+		{
+		transport->Send( aParams, aResponse, aId, aStatus );
+		}
+	else
+	    {	
+        TRequestStatus* stat = &aStatus;
+        User::RequestComplete( stat, KErrNotFound );
+	    }
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::SendToTransportL
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::SendToTransportL(
+    const TSIPTransportParams& aParams,
+    CSIPRequest& aRequest,
+    TBool aForceUDP,
+    const CUri8* aOutboundProxy,
+	const TInetAddr& aAddr,
+	TRequestStatus &aStatus )
+	{
+	TUint origTransport = 
+	    UpdateTransportIfNeededL( aRequest, aParams, aForceUDP, aAddr );
+
+    // If there's saved settings regarding remote address, use them instead of
+    // address passed from upper layers (probably only the port differs)
+    const TInetAddr* address = 
+        iSettingsList->SavedRemoteAddr( aParams.TransportId() );
+    if ( !address )
+        {
+        address = &aAddr;
+        }
+        
+    TInetAddr localAddr;  
+    GetLocalAddrL( localAddr, address );    
+    iRequestQueue->NATTraverseL( aParams, 
+                                 aRequest, 
+                                 aForceUDP,
+                                 *address, 
+                                 aOutboundProxy,
+                                 origTransport, 
+                                 aStatus,
+                                 localAddr );
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::ContinueSendToTransportL
+// -----------------------------------------------------------------------------
+//	
+void CSipConnection::ContinueSendToTransportL( 
+    const TSIPTransportParams& aParams,
+    CSIPRequest& aRequest,
+    TBool aForceUDP,
+    const TInetAddr& aRemoteAddr,
+    TUint aLocalPort,
+    TUint aOrigTransport,
+    TRequestStatus& aStatus,
+    TBool aPublicAddrResolved )
+    {
+    __ASSERT_ALWAYS( IsConnectionActive(), User::Leave( KErrNotReady ) );
+
+	CTransportBase* transport = 
+	    FindTransportL( aParams, &aRequest, aRemoteAddr, aLocalPort );
+	if ( transport != 0 )
+		{
+		aStatus = KRequestPending;
+		transport->Send( aParams, 
+		                 aRequest,
+		                 aForceUDP,
+		                 aRemoteAddr, 
+		                 aOrigTransport, 
+		                 aStatus, 
+		                 aPublicAddrResolved );
+		}
+	else
+		{
+		if ( aRequest.HasHeader( SIPStrings::StringF(SipStrConsts::EViaHeader) ) )
+			{
+            if ( IsTransportUdp( &aRequest ) )
+                {
+            	AddUdpListenerL( 
+            	    TSIPTransportParams( KDefaultOwnerId, iIapId ),
+            	    KDefaultSipPort );
+            	}
+            else
+            	{	
+            	CreateConnectedTransportPointL( aParams, aRequest, aRemoteAddr );
+            	}
+
+            transport = FindTransportL( aParams, &aRequest, aRemoteAddr );
+            if ( transport )
+                {
+                aStatus = KRequestPending;
+                transport->Send( aParams, 
+                                 aRequest,
+                                 aForceUDP, 
+                                 aRemoteAddr, 
+                                 aOrigTransport, 
+                                 aStatus,
+                                 aPublicAddrResolved );
+            	}
+            else
+            	{
+            	TRequestStatus* stat = &aStatus;
+            	User::RequestComplete( stat, KErrNotReady );
+            	}	
+			}
+		}
+    }
+
+// -----------------------------------------------------------------------------
+// CSipConnection::RequestFailed
+// -----------------------------------------------------------------------------
+//   
+void CSipConnection::RequestFailed( TRequestStatus& aStatus, TInt aError )
+    {
+    if ( aStatus == KRequestPending )
+        {
+        TRequestStatus* status = &aStatus;
+		User::RequestComplete( status, aError );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSipConnection::GetUdpSocketL
+// -----------------------------------------------------------------------------
+//    
+RSocket& CSipConnection::GetUdpSocketL( 
+    const TSIPTransportParams& aParams, 
+    const TInetAddr& aRemoteAddr,
+    TUint& aLocalPort,
+    MSocketUsagePermissionObserver* aObserver,
+    TBool& aPermissionToUse )
+    {
+    CTransportBase* transport = 
+        FindTransport( aParams, 
+                       SIPStrings::StringF( SipStrConsts::EUDP ), 
+                       aRemoteAddr,
+                       aLocalPort,
+                       EFalse );
+    if ( !transport )
+        {
+        if ( !aLocalPort )
+            {
+            aLocalPort = iSettingsList->GetPrivatePortL( aParams );	
+            }
+        transport = AddUdpListenerL( aParams, aLocalPort, ETrue );
+        }
+
+    RSocket* udpSocket = 
+        transport->AcquireUdpSocket( aObserver, aRemoteAddr, aPermissionToUse );
+        
+    __ASSERT_ALWAYS( udpSocket, User::Leave( KErrNotFound ) );
+    
+    return *udpSocket;
+    }
+
+// -----------------------------------------------------------------------------
+// CSipConnection::UdpSocketFree
+// -----------------------------------------------------------------------------
+//       
+void CSipConnection::UdpSocketFree( 
+    const TSIPTransportParams& aParams,
+    const TInetAddr& aRemoteAddr,
+    TUint aLocalPort,
+    MSocketUsagePermissionObserver* aObserver,
+    RSocket& aSocket )
+    {
+    CTransportBase* transport = 
+        FindTransport( aParams, 
+                       SIPStrings::StringF( SipStrConsts::EUDP ), 
+                       aRemoteAddr,
+                       aLocalPort,
+                       EFalse );
+    if ( transport )
+        {
+        transport->UdpSocketReleased( aObserver, aSocket );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSipConnection::UpdateTransportIfNeededL
+// -----------------------------------------------------------------------------
+//
+TUint CSipConnection::UpdateTransportIfNeededL( 
+    CSIPMessage& aMessage,
+    const TSIPTransportParams& aParams,
+    TBool aForceUDP,
+    const TInetAddr& aAddr )
+	{
+    TUint origTransport = TransportProtocolL( aMessage );
+		
+	CSIPViaHeader* via = TopViaHeader( &aMessage );
+	
+	if ( via )
+	    {
+    	TBool tlsForced = 
+	        iSettingsList->HasSavedTLSTransportInfo( aParams.TransportId() );
+	    
+		if ( tlsForced && origTransport != KProtocolTls )
+		    {
+		    via->SetTransportL( SIPStrings::StringF(SipStrConsts::ETLS) );
+		    
+		    // Upper layer may give incorrect port information in some 
+		    // situations when TLS is in use, ensure that at least
+		    // default TLS port is used.
+		    iSettingsList->SaveTLSRemoteL( aParams, aAddr );
+		    }
+	    else if ( origTransport == KProtocolInetUdp && !aForceUDP &&
+	            ( aMessage.EncodedHeaderPartLengthL() +
+    		      aMessage.Content().Length() ) > KMaxUdpMessageSize )
+	        {
+	       	via->SetTransportL( SIPStrings::StringF(SipStrConsts::ETCP) );
+	        }
+	    else
+	        {
+	        }
+	    }
+	    
+    return origTransport;
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::CreateConnectedTransportPointL
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::CreateConnectedTransportPointL( 
+    const TSIPTransportParams& aParams,
+    CSIPMessage& aMessage, 
+    const TInetAddr& aAddress )
+	{
+	TUint protocol = TransportProtocolL( aMessage );
+	switch ( protocol )
+	    {
+	    case KProtocolInetTcp:
+	        {
+	        CreateTcpTransportPointL( aParams, aAddress );
+	        break;
+	        }
+	    case KProtocolTls:
+	        {
+	        CreateTlsTransportPointL( aParams, aAddress );
+	        //Check if the SIP message is request.Below code sets the
+			//domain name into CTransportTls object which will be later
+			//used in domain name matching during TLS Negotiation
+	        HBufC8 *domainName = NULL;
+	        CTransportTls *transport;
+	        if(aMessage.IsRequest())
+	        {
+	        	//If the SIP request has Route header then the host part will be extracted
+	        	//from the Route header
+	        	const RStringF route = SIPStrings::StringF(SipStrConsts::ERouteHeader);	        	
+	        	if(aMessage.HasHeader(route))
+	        	{
+	        		TSglQueIter<CSIPHeaderBase> iter = aMessage.Headers( route );
+	        	    iter.SetToFirst();
+	        	    CSIPHeaderBase* header = iter;
+	        	    if ( header )
+	        	    {
+	        			CSIPRouteHeader* routeHeader =	static_cast<CSIPRouteHeader*>( header );
+	        			domainName = routeHeader->SIPAddress().URI().SIPURI()->HostPort().Host().AllocL();	        			
+	        		}	        
+	        	}
+	        	else
+	        	{
+	        		//If the Route header is absent from the SIP Request, request-line
+	        		//gets preference and host part is extracted from the request-line					
+       				CSIPRequest &request = static_cast<CSIPRequest&>(aMessage ) ;
+       				domainName = request.RequestURI()->SIPURI()->HostPort().Host().AllocL();
+	        	}	        	
+	        }
+	        else
+	        {
+	        	//Message is response. Host part will be extracted from the top
+	        	//Via header
+	            CSIPViaHeader* viaHeader = TopViaHeader( &aMessage );
+	            domainName = viaHeader->SentByHostPort().Host().AllocL();	            
+	        }
+	        transport = static_cast<CTransportTls*>(FindTransport( aParams, 
+	        	        								SIPStrings::StringF( SipStrConsts::ETLS ),
+	        	        								aAddress));
+			//If the domain name is of type "Text", set the domain name for the
+			//TLS object.
+			if ( ( UriUtils::HostType( *domainName ) == UriUtils::ETextHost ))
+		        transport->SetDomainNameL(domainName->Des());
+		    delete domainName;	
+	        break;
+	        }
+	    default:
+	        {
+	        User::Leave( KErrArgument );
+	        break;
+	        }
+	    }
+	}
+	
+// -----------------------------------------------------------------------------
+// CSipConnection::CreateTcpTransportPointL
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::CreateTcpTransportPointL( 
+    const TSIPTransportParams& aParams, 
+    const TInetAddr& aAddress )
+	{
+	// Leave if tcp connection with remote address exists already
+	CTransportBase* listItem = 0;
+	iListIter.SetToFirst();
+	while( ( listItem = iListIter++ ) != 0 )
+		{
+		if( listItem->HasRemoteHost( aParams, 
+		                             aAddress, 
+		                             SIPStrings::StringF(SipStrConsts::ETCP) ) )
+		    {
+		    User::Leave( KErrSIPTransportFailure );
+		    }
+		}	
+	
+	CTransportBase* transport =	
+	    CTransportTcp::NewLC( 
+	        iServer, iFinder, iTaFactory,
+			*this, iTimer, aParams, aAddress, iTOne,
+			*iServerResolver, Connection(), iSigCompHandler, 
+			iSettingsList->SavedLocalSendPort( aParams.TransportId() ),
+			iNetworkInfo, *iSettingsList, iNATTraversal );        
+	AddTransportL( transport );
+	CleanupStack::Pop( transport );
+	}
+	
+// -----------------------------------------------------------------------------
+// CSipConnection::CreateTlsTransportPointL
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::CreateTlsTransportPointL( 
+    const TSIPTransportParams& aParams, 
+    const TInetAddr& aAddress )
+	{
+	// Leave if tcp connection with remote address exists already
+	CTransportBase* listItem = 0;
+	iListIter.SetToFirst();
+	while( ( listItem = iListIter++ ) != 0 )
+		{
+		if( listItem->HasRemoteHost( aParams, 
+		                             aAddress,
+		                             SIPStrings::StringF(SipStrConsts::ETLS) ) )
+		    {
+		    User::Leave( KErrSIPTransportFailure );
+		    }
+		}	
+	
+	CTransportBase* transport =	
+	    CTransportTls::NewLC( 
+	        iServer, iFinder, iTaFactory,
+			*this, iTimer, aParams, aAddress, iTOne,
+			*iServerResolver, Connection(), iSigCompHandler, 
+			iNetworkInfo, *iSettingsList, iNATTraversal );        
+	AddTransportL( transport );
+	CleanupStack::Pop( transport );
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::IsTransportUdp
+// -----------------------------------------------------------------------------
+//
+TBool CSipConnection::IsTransportUdp( CSIPMessage* aMessage )
+	{
+	CSIPViaHeader* via = TopViaHeader( aMessage );
+	if( via )
+		{
+		if( via->Transport() == SIPStrings::StringF(SipStrConsts::EUDP) )
+			{
+			return ETrue;
+			}
+		}
+
+	return EFalse;
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::TransportProtocolL
+// -----------------------------------------------------------------------------
+//	
+TUint CSipConnection::TransportProtocolL( CSIPMessage& aMessage )
+    {
+    CSIPViaHeader* via = TopViaHeader( &aMessage );
+    __ASSERT_ALWAYS( via, User::Leave( KErrNotFound ) );
+
+	RStringF transport = via->Transport(); 
+	if ( transport == SIPStrings::StringF( SipStrConsts::EUDP ) )
+		{
+		return KProtocolInetUdp;
+		}
+    else if ( transport == SIPStrings::StringF( SipStrConsts::ETCP ) )
+		{
+		return KProtocolInetTcp;
+		}
+    else if ( transport == SIPStrings::StringF( SipStrConsts::ETLS ) )
+		{
+		return KProtocolTls;
+		}
+	else
+	    {
+	    User::Leave( KErrNotSupported );
+	    }
+	return 0;
+    }
+
+// -----------------------------------------------------------------------------
+// CSipConnection::ResetTransportsL
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::ResetTransportsL()
+	{
+	RemoveAllTransports();
+	TSIPTransportParams defaultParams( KDefaultOwnerId, iIapId );
+	AddTcpListenerL( defaultParams, KDefaultSipPort );
+	AddUdpListenerL( defaultParams, KDefaultSipPort );
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::IsInList
+// -----------------------------------------------------------------------------
+//
+TBool CSipConnection::IsInList( CTransportBase* aTransport )
+	{
+	if( aTransport )
+		{
+		CTransportBase* listItem;
+		iListIter.SetToFirst();
+		while ( ( listItem = iListIter++ ) != 0 )
+			{
+			if( listItem == aTransport )
+				{
+				return ETrue;
+				}
+			}
+		}
+	return EFalse;
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::AddTransportL
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::AddTransportL( CTransportBase* aTransport )
+	{
+	if( aTransport )
+		{
+		if( !IsInList( aTransport ) )
+			{
+			iList.AddLast( *aTransport );
+			}
+		else
+			{
+			User::Leave( KErrAlreadyExists );
+			}
+		}
+	else
+		{
+		User::Leave( KErrGeneral );
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::RemoveTransport
+// -----------------------------------------------------------------------------
+//
+TInt CSipConnection::RemoveTransport( CTransportBase* aTransport )
+	{
+	if( IsInList( aTransport ) )
+		{
+		iList.Remove( *aTransport );
+		delete aTransport;
+		return KErrNone;
+		}
+	else
+		{
+		return KErrNotFound;
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::RemoveAllTransports
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::RemoveAllTransports()
+	{
+	CTransportBase* listItem( NULL );
+	iListIter.SetToFirst();
+	while ( ( listItem = iListIter++ ) != 0 )
+		{
+		iList.Remove( *listItem );
+		delete listItem;
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::FindTransportL
+// -----------------------------------------------------------------------------
+//
+CTransportBase* CSipConnection::FindTransportL( 
+    const TSIPTransportParams& aParams,
+    CSIPMessage* aMessage,
+	TTransactionId aId,
+	TBool aIsStrict )
+	{
+	iListIter.SetToFirst();
+
+	CTransportBase* listItem = NULL;
+	while ( ( listItem = iListIter++ ) != 0 )
+		{
+		if( listItem->HandleL( aParams, aMessage, aId, aIsStrict ) )
+			{
+			return listItem;
+			}
+		}
+	return 0;
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::FindTransportL
+// -----------------------------------------------------------------------------
+//
+CTransportBase* CSipConnection::FindTransportL( 
+    const TSIPTransportParams& aParams,
+    CSIPMessage* aMessage,
+	const TInetAddr& aRemoteAddr,
+	TUint aLocalPort,
+	TBool aIsStrict )
+	{
+	CTransportBase* listItem;
+	iListIter.SetToFirst();
+
+	while ( ( listItem = iListIter++ ) != 0 )
+		{
+		if ( listItem->HandleL( aParams, 
+		                        aMessage, 
+		                        aRemoteAddr, 
+		                        aLocalPort,
+		                        aIsStrict ) )
+			{
+			return listItem;
+			}
+		}
+	return 0;
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::FindTransportL
+// -----------------------------------------------------------------------------
+//
+CTransportBase* CSipConnection::FindTransport( 
+    const TSIPTransportParams& aParams,
+    RStringF aProtocol,
+	const TInetAddr& aRemoteAddr,
+	TUint aLocalPort,
+	TBool aIsStrict )
+	{
+	CTransportBase* listItem;
+	iListIter.SetToFirst();
+	while ( ( listItem = iListIter++ ) != 0 )
+		{
+		if ( listItem->HandleMessage( aParams, 
+		                              aProtocol, 
+		                              aRemoteAddr, 
+		                              aLocalPort,
+		                              aIsStrict ) )
+			{
+			return listItem;
+			}
+		}
+	return 0;
+	}
+	
+// -----------------------------------------------------------------------------
+// CSipConnection::RemoveTcpSender
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::RemoveTcpSender( CTcpResponseSender* aThis )
+	{
+	if ( !iTcpSenderList.IsEmpty() )
+		{
+		iTcpSenderList.Remove( *aThis );
+		delete aThis;
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::RemoveAllTcpSender
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::RemoveAllTcpSender()
+	{
+	CTcpResponseSender* listItem( NULL );
+	iTcpSenderListIter.SetToFirst();
+	while ( ( listItem = iTcpSenderListIter++ ) != 0 )
+		{
+		iTcpSenderList.Remove( *listItem );
+		delete listItem;
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::TcpConnected
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::TcpConnected( const TInetAddr& aAddr )
+	{
+	CTcpResponseSender* listItem( NULL );
+	iTcpSenderListIter.SetToFirst();
+	while ( ( listItem = iTcpSenderListIter++ ) != 0 )
+		{
+		listItem->Connected( aAddr );
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::ReRouteL
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::ReRouteL( TUint aProtocol, COutgoingData* aData )
+	{
+	__ASSERT_ALWAYS( aData, User::Leave( KErrArgument ) );
+
+	const TSIPTransportParams& tpParams = aData->TransportParams();
+	if ( aProtocol == KProtocolInetTcp &&
+		 aData->Message().IsRequest() )
+		{
+		CSIPViaHeader* via = TopViaHeader( &aData->Message() );
+		if(via)
+		{
+		    via->SetTransportL( SIPStrings::StringF(SipStrConsts::ETCP) );
+		}
+				
+		// Public address resolved value can be passed as true, since
+		// at this point all necessary via and contact header updates
+		// have been done (i.e. no need to update).
+		ContinueSendToTransportL(
+		    tpParams,
+		    static_cast<CSIPRequest&>( aData->Message() ),
+		    aData->ForceUDP(),
+			aData->Address(), 
+			0,
+			aData->OrigTransport(), 
+			*aData->Status(),
+			ETrue );
+		delete aData;
+		return;
+		}
+
+	if ( aProtocol == KProtocolInetTcp )
+		{
+		CTcpResponseSender* tcpsender( NULL );
+		while ( (tcpsender = iTcpSenderListIter++ ) != 0 )
+			{
+			if ( tcpsender->IsInProgress( *aData ) )
+				{
+				tcpsender->ConnectionFailedL();
+				delete aData;
+				return;
+				}
+			}
+		tcpsender =
+			new ( ELeave ) CTcpResponseSender( tpParams, 
+			                                   *iServerResolver, 
+			                                   *this );
+		iTcpSenderList.AddLast( *tcpsender );
+		tcpsender->ResolveL( *aData );
+		tcpsender->SetData( aData );
+		}
+
+	if ( aProtocol == KProtocolInetUdp &&
+		 ( aData->Message().EncodedHeaderPartLengthL() +
+		   aData->Message().Content().Length() ) > KMaxMessageLength )
+		{
+		TRequestStatus* stat = aData->Status();
+		User::RequestComplete( stat, KErrCouldNotConnect );
+		delete aData;
+		return;
+		}
+
+	if ( aProtocol == KProtocolInetUdp )
+		{
+		CSIPViaHeader* via = TopViaHeader( &aData->Message() );
+		if ( via )
+			{
+			via->SetTransportL( SIPStrings::StringF(SipStrConsts::EUDP) );
+			}
+		CSender* send = GetSender( tpParams, aProtocol, aData->Address() );
+		if ( send )
+			{
+			send->SendL( aData );
+			}
+		else
+			{
+			AddUdpListenerL( 
+			    TSIPTransportParams( KDefaultOwnerId, iIapId ),
+			    KDefaultSipPort );
+			send = GetSender( tpParams, aProtocol, aData->Address() );
+			if ( send )
+				{
+				send->SendL( aData );
+				}
+			else
+				{
+				TRequestStatus* stat = aData->Status();
+				User::RequestComplete( stat, KErrCouldNotConnect );
+				delete aData;
+				}
+			}
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::GetSender
+// -----------------------------------------------------------------------------
+//
+CSender* CSipConnection::GetSender( 
+    const TSIPTransportParams& aParams,
+    TUint aProtocol, 
+    const TInetAddr& aAddr )
+	{
+	CTransportBase* listItem;
+	iListIter.SetToFirst();
+
+	CSender* sender = NULL;
+	while( ( ( listItem = iListIter++ ) != 0 ) && !sender )
+		{
+		sender = listItem->Sender( aParams, aProtocol, aAddr );
+		}
+
+	return sender;
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::AddListenerL
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::AddListenerL( 
+    const TSIPTransportParams& aParams,
+    TUint aProtocol, 
+    TUint aPort )
+	{
+	AddTcpListenerL( aParams, aPort );
+	if( aProtocol != KProtocolInetTcp )
+		{
+		AddUdpListenerL( aParams, aPort );
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::AddTcpListenerL
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::AddTcpListenerL( 
+    const TSIPTransportParams& aParams, 
+    TUint aPort,
+    TBool aIsReserved )
+	{
+	if( !IsListened( KProtocolInetTcp, aPort ) )
+		{                       
+		CTransportBase* transportTcp =
+			CTcpListeningPoint::NewLC( iServer, iFinder, iTaFactory, *this,
+									   iTimer, aPort, iTOne, *iServerResolver,
+									   Connection(), iSigCompHandler,
+									   iNetworkInfo, *iSettingsList, aParams,
+									   iNATTraversal );
+		AddTransportL( transportTcp );
+		CleanupStack::Pop( transportTcp );
+		transportTcp->WaitL();
+		}
+    else
+        {
+        __ASSERT_ALWAYS( !aIsReserved, User::Leave( KErrSIPTransportFailure ) );
+        }
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::AddUdpListenerL
+// -----------------------------------------------------------------------------
+//
+CTransportBase* CSipConnection::AddUdpListenerL( 
+    const TSIPTransportParams& aParams,
+    TUint aPort,
+    TBool aIsReserved,
+    TBool aOnlyForReceiving )
+	{
+	CTransportBase* transport( NULL );
+	if( !IsListened( KProtocolInetUdp, aPort ) )
+		{
+		transport =
+			CTransportUdp::NewLC( iServer, aPort, iFinder,
+			                      iTaFactory, *this, iTimer, *iServerResolver,
+			                      Connection(), iSigCompHandler, iTOne,
+			                      iNetworkInfo, *iSettingsList, aParams,
+			                      iNATTraversal, aOnlyForReceiving );
+		AddTransportL( transport );
+		CleanupStack::Pop( transport );
+		transport->WaitL();
+		}
+    else
+        {
+        __ASSERT_ALWAYS( !aIsReserved, User::Leave( KErrSIPTransportFailure ) );
+        }
+        
+    return transport;
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::AddTcpListenerUserL
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::AddTcpListenerUserL( 
+    const TSIPTransportParams& aOldParams,
+    const TSIPTransportParams& aParams,
+    TUint aReceivePort )
+    {
+    CTransportBase* listItem( NULL );
+	iListIter.SetToFirst();
+	
+	TBool added( EFalse );
+   	while ( ( listItem = iListIter++ ) != 0 && !added )
+		{
+		if( listItem->Handle( aOldParams.TransportId() ) &&
+		    listItem->ProtocolType() == KProtocolInetTcp )
+			{
+			added = listItem->AddUserL( aParams, aReceivePort );
+			}
+		}
+	if ( !added )
+	    {
+        User::Leave( KErrNotFound );
+	    }
+    }
+    
+// -----------------------------------------------------------------------------
+// CSipConnection::AddUdpListenerUserL
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::AddUdpListenerUserL( 
+    const TSIPTransportParams& aOldParams,
+    const TSIPTransportParams& aParams,
+    TUint aReceivePort )
+    {
+    CTransportBase* listItem( NULL );
+	iListIter.SetToFirst();
+	
+	TBool added( EFalse );
+   	while ( ( listItem = iListIter++ ) != 0 && !added )
+		{
+		if( listItem->Handle( aOldParams.TransportId() ) &&
+		    listItem->ProtocolType() == KProtocolInetUdp )
+			{
+			added = listItem->AddUserL( aParams, aReceivePort );
+			}
+		}
+	if ( !added )
+	    {
+        User::Leave( KErrNotFound );
+	    }
+    }
+    
+// -----------------------------------------------------------------------------
+// CSipConnection::IsListened
+// -----------------------------------------------------------------------------
+//
+TBool CSipConnection::IsListened( TInt aProtocol, TUint aPort )
+	{
+	CTransportBase* listItem( NULL );
+	iListIter.SetToFirst();
+
+	while ( ( listItem = iListIter++ ) != 0 )
+		{
+		if( listItem->IsWaiting( aProtocol, aPort ) )
+			{
+			return ETrue;
+			}
+		}
+	return EFalse;
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::CancelAllRequests
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::CancelAllRequests( CSIPConnection::TState aReason )
+	{
+	CTransportBase* listItem( NULL );
+	iListIter.SetToFirst();
+	while ( ( listItem = iListIter++ ) != 0 )
+		{
+		listItem->CancelAllRequests( aReason );
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::IcmpError
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::IcmpError( const TInetAddr& aAddress )
+	{
+	TRAP_IGNORE( NotifyIcmpErrorL( aAddress ) )
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::GetByURIL
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::GetByURIL( const TSIPTransportParams& aParams,
+                                const CURIContainer& aURI,
+                                RPointerArray<MSIPResolvingResult>& aResult,
+		                        MSIPServerResolverObserver* aObserver )
+	{
+	__ASSERT_ALWAYS( iServerResolver, User::Leave( KErrNotReady ) );
+	
+	// Have to do const cast in order to get binding observer
+	MSIPNATBindingObserver* bindingObserver = 
+	    const_cast<TSIPTransportParams&>( aParams ).NATBindingObserver();
+
+	TBool persistentConnectionFound( EFalse );
+	TInetAddr* remoteAddr = 0;
+	TUint protocol = 0;
+	
+	CTransportBase* listItem;
+    iListIter.SetToFirst();
+	while ( ( listItem = iListIter++ ) != 0 && !persistentConnectionFound )
+		{
+		protocol = listItem->ProtocolType();
+		remoteAddr = listItem->PersistentRemoteAddr( bindingObserver );
+		
+		persistentConnectionFound = 
+		    ( remoteAddr &&
+		    ( protocol == KProtocolInetTcp || protocol == KProtocolTls ) );
+	    }
+	    
+	TBool skipNaptrAndSrv = aParams.SkipNaptrAndSrv();    
+	    
+	if ( persistentConnectionFound )
+	    {
+	    CURIContainer* uriContainer = CURIContainer::NewLC( aURI );
+		UpdateURIL( *uriContainer, *remoteAddr, protocol );
+		iServerResolver->GetByURIL( *uriContainer, skipNaptrAndSrv, 
+		                            aResult, aObserver );
+		CleanupStack::PopAndDestroy( uriContainer );
+		return;
+	    }
+
+    iServerResolver->GetByURIL( aURI, skipNaptrAndSrv, aResult, aObserver );
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::CancelGetByUri
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::CancelGetByUri( MSIPServerResolverObserver* aObserver )
+	{
+	if( iServerResolver )
+	    { 
+    	iServerResolver->Cancel( aObserver );
+	    }
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::GetLocalAddress
+// -----------------------------------------------------------------------------
+//
+TInt CSipConnection::GetLocalAddress( TInetAddr& aAddr )
+	{
+	if ( !iLocalAddrResolver )
+		{
+		return KErrNotReady;
+		}
+
+	TRAPD( err, GetLocalAddrL( aAddr, NULL ) );
+		
+	return err;
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::IsLocalAddr
+// -----------------------------------------------------------------------------
+//
+TBool CSipConnection::IsLocalAddr( TInetAddr& aAddr ) const
+    {
+    return iLocalAddrResolver->IsLocalAddr( aAddr );
+    }
+
+// -----------------------------------------------------------------------------
+// CSipConnection::GetLocalAddrL
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::GetLocalAddrL( 
+    TInetAddr& aAddr, 
+    const TInetAddr* aNextHop )
+	{
+	if( iLocalAddrResolver )
+		{
+	    iLocalAddrResolver->RefreshLocalAddressesL();
+	    FillWithMatchingAddrFamily( aAddr, aNextHop );
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::GetLocalIPAddr
+// -----------------------------------------------------------------------------
+//
+TBool CSipConnection::GetLocalIPAddr( TUint aFamily, TInetAddr& aAddr )
+    {
+    TBool found( EFalse );
+    if( iLocalAddrResolver )
+		{
+		if ( aFamily == KAfInet )
+		    {
+		    if ( !iLocalAddrResolver->IPv4Addr().IsUnspecified() )
+		        {
+        		aAddr = iLocalAddrResolver->IPv4Addr();
+        		found = ETrue;
+		        }
+		    }
+		else
+		    {
+		    if ( !iLocalAddrResolver->IPv6Addr().IsUnspecified() )
+		        {
+        		aAddr = iLocalAddrResolver->IPv6Addr();
+        		found = ETrue;
+		        }
+		    }
+
+		}
+	return found;
+    }
+
+// -----------------------------------------------------------------------------
+// CSipConnection::FillWithMatchingAddrFamily
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::FillWithMatchingAddrFamily( 
+    TInetAddr& aAddr,
+    const TInetAddr* aNextHop )
+    {
+    __SIP_ADDR_LOG("CSipConnection::FillWithMatchingAddrFamily: local IPv6 addr",
+                   iLocalAddrResolver->IPv6Addr())
+    __SIP_ADDR_LOG("CSipConnection::FillWithMatchingAddrFamily: local IPv4 addr",               
+                   iLocalAddrResolver->IPv4Addr())
+    
+    if ( !iLocalAddrResolver->IPv4Addr().IsUnspecified() )
+	    {
+	    aAddr = iLocalAddrResolver->IPv4Addr();
+	    }
+	else
+	    {
+	    aAddr = iLocalAddrResolver->IPv6Addr();
+	    }
+    
+	if ( aNextHop )
+	    {
+        __SIP_ADDR_LOG("CSipConnection::FillWithMatchingAddrFamily: next hop addr",               
+                       *aNextHop)	    
+	    
+                       
+	    if ( aNextHop->Address() ) // Contains IPv4 address
+	        {
+        	__SIP_INT_LOG1("CSipConnection::FillWithMatchingAddrFamily: next hop family",
+                       KAfInet)
+	        if ( iLocalAddrResolver->IPv4Addr().IsUnspecified() &&
+	             ( aAddr.IsV4Compat() || aAddr.IsV4Mapped() ) )
+	            {
+	            aAddr.ConvertToV4();
+	            }
+	        }
+	    else
+	        {
+        	__SIP_INT_LOG1("CSipConnection::FillWithMatchingAddrFamily: next hop family",
+                       KAfInet6)
+	        if ( iLocalAddrResolver->IPv6Addr().IsUnspecified() )
+	            {
+	            aAddr = iLocalAddrResolver->IPv4Addr();
+	            aAddr.ConvertToV4Mapped();
+	            }
+	        else
+	            {
+	            aAddr = iLocalAddrResolver->IPv6Addr();
+	            }
+	        }
+	    }
+	__SIP_ADDR_LOG("CSipConnection::FillWithMatchingAddrFamily returns",aAddr)
+    }
+
+// -----------------------------------------------------------------------------
+// CSipConnection::DecreaseUserCount
+// -----------------------------------------------------------------------------
+//
+TInt CSipConnection::DecreaseUserCount( const TSIPTransportParams& aParams )
+	{
+	__SIP_ASSERT_RETURN_VALUE( iUserCount > 0, KErrUnderflow );	
+	
+	iSettingsList->RemoveSettings( aParams );
+	
+	// Remove all related transports, default transports are not removed
+	//
+   	CTransportBase* listItem;
+	iListIter.SetToFirst();
+
+	while ( ( listItem = iListIter++ ) != 0 )
+		{
+		if ( listItem->Remove( aParams ) )
+			{
+			RemoveTransport( listItem );
+			}
+		}
+		
+	iUserCount--;	
+	return iUserCount;
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::IncreaseUserCount
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::IncreaseUserCount()
+	{
+	iUserCount++;
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::Handle
+// -----------------------------------------------------------------------------
+//
+TBool CSipConnection::Handle( TUint32 aIapId ) const
+	{
+	return ( aIapId == iIapId );
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::IapId
+// -----------------------------------------------------------------------------
+//	
+TUint32 CSipConnection::IapId() const
+    { 
+    return iIapId;
+    }
+    
+// -----------------------------------------------------------------------------
+// CSipConnection::ReserveTransportL
+// -----------------------------------------------------------------------------
+//		
+void CSipConnection::ReserveTransportL( 
+    const TSIPTransportParams& aOldTransportParams,
+    const TSIPTransportParams& aTransportParams,
+    TUint aLocalSendPort,
+	TUint aLocalReceivePort,
+	const TInetAddr& aRemoteAddr,
+	TUint aRemoteSendPort )
+    {
+    // First reserve ports and save information about transport.
+    // - will leave with KErrSIPTransportFailure if some of the ports are 
+    // already reserved (if reservations for old transport id exist already,
+    // duplicate reservations are allowed).
+    
+    if ( !iSettingsList->SaveTransportInfoL( aOldTransportParams,
+                                             aTransportParams, 
+                                             aLocalSendPort, 
+                                             aLocalReceivePort,  
+                                             aRemoteAddr,
+                                             aRemoteSendPort ) )
+        {
+        // Because no previous settings matching aOldTransportParams were found
+        // also listeners don't exist yet, create them
+        //
+        AddTcpListenerL( aTransportParams, aLocalReceivePort, ETrue );
+    	
+    	AddUdpListenerL( aTransportParams, aLocalReceivePort, ETrue, ETrue );
+        }
+   else
+        {
+        // For existing tcp and udp listeners, add knowledge about second user
+        //
+        AddTcpListenerUserL( aOldTransportParams, 
+                             aTransportParams, 
+                             aLocalReceivePort );
+                             
+        AddUdpListenerUserL( aOldTransportParams, 
+                             aTransportParams, 
+                             aLocalReceivePort );                  
+        }
+        
+   AddUdpListenerL( aTransportParams, aLocalSendPort, ETrue );
+	                                 
+   // TCP connection for outgoing requests is not created until sending occurs
+   
+   }
+
+// -----------------------------------------------------------------------------
+// CSipConnection::ReserveTLSTransportL
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::ReserveTLSTransportL( 
+    TSIPTransportParams& aTransportParams )
+    {
+    iSettingsList->SaveTLSTransportInfoL( aTransportParams );
+    }
+    
+// -----------------------------------------------------------------------------
+// CSipConnection::RemoveTransport
+// -----------------------------------------------------------------------------
+//				                
+TBool CSipConnection::RemoveReservedTransport( 
+    TUint32 aTransportId, 
+    MSIPTransportRemovalObserver* aRemovalObserver,
+    TInt& aNumAsyncRemovals )
+    {
+    // First remove corresponding settings
+    if( !iSettingsList->RemoveSettings( aTransportId ) )
+        {
+        return EFalse;
+        }
+    
+    // If some settings were removed there is also transports which has to 
+    // be removed
+   	CTransportBase* listItem;
+	iListIter.SetToFirst();
+
+	while ( ( listItem = iListIter++ ) != 0 )
+		{
+		if ( listItem->Handle( aTransportId ) )
+			{
+			// Remove call will remove everything inside the transport related
+			// to the transport id and if Remove() returns ETrue, transport
+			// can be removed completely (if asynchronous shutdown is
+			// not required)
+			TBool lastUser = listItem->Remove( aTransportId );
+			
+			if ( listItem->Shutdown( aTransportId, aRemovalObserver ) )
+			    {
+			    // Caller has to wait asynchronous completion of transport
+			    // removal
+			    aNumAsyncRemovals++;
+			    }
+			else if ( lastUser )
+			    {
+			    RemoveTransport( listItem );
+			    }
+			else
+			    {
+			    }
+			}
+		}
+    
+    return ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// CSipConnection::Match
+// -----------------------------------------------------------------------------
+//
+TBool CSipConnection::Match( const TDesC8& aAddress )
+	{
+	TInetAddr address;
+	GetLocalAddress( address );
+
+	TBuf16< KMaxAddressLength > addressout16;
+	TBuf8< KMaxAddressLength > addressout8;
+	address.Output( addressout16 );
+	addressout8.Copy( addressout16 );
+
+	return ( addressout8 == aAddress );
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::CreateTransportResourcesL
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::CreateTransportResourcesL()
+	{
+	__SIP_LOG( "CreateTransportResourcesL" )
+	//Resources must not exist already
+	__SIP_ASSERT_LEAVE( !iIcmpReceiver, KErrAlreadyExists );
+	__SIP_ASSERT_LEAVE( !iServerResolver, KErrAlreadyExists );
+	__SIP_ASSERT_LEAVE( !iLocalAddrResolver, KErrAlreadyExists );
+
+	iIcmpReceiver = CIcmpReceiver::NewL( *this, iServer );
+	iServerResolver = CSIPServerResolver::NewL( iServer, Connection() );
+	iLocalAddrResolver = 
+	    CLocalAddrResolver::NewL( iServer, Connection());
+	iRequestQueue = COutgoingRequestQueue::NewL( *this, 
+	                                             iNATTraversal, 
+	                                             Connection(), 
+	                                             iIapId );
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::CreateDefaultTransportsL
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::CreateDefaultTransportsL()
+    {
+    TSIPTransportParams defaultParams( KDefaultOwnerId, iIapId );
+    if ( !IsListened( KProtocolInetTcp, KDefaultSipPort ) )
+        {
+        AddTcpListenerL( defaultParams, KDefaultSipPort );
+        }
+    if ( !IsListened( KProtocolInetUdp, KDefaultSipPort ) )
+        {
+        AddUdpListenerL( defaultParams, KDefaultSipPort );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSipConnection::ReleaseTransportResources
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::ReleaseTransportResources( TBool aReleaseAllResources )
+	{
+	__SIP_LOG( "ReleaseTransportResources" )
+
+	delete iIcmpReceiver;
+	iIcmpReceiver = NULL;
+	RemoveAllTransports();
+	RemoveAllTcpSender();
+	delete iServerResolver;
+	iServerResolver = NULL;
+	delete iLocalAddrResolver;
+	iLocalAddrResolver = NULL;
+	delete iRequestQueue;
+	iRequestQueue = NULL;
+
+    if ( aReleaseAllResources )
+        {
+#if ( !defined( __WINS__ ) && !defined( __WINSCW__ ) )
+	    // In HW RConnection must be closed when network coverage is lost	
+   	    CloseConnection();      
+#endif
+        }
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::DoTransportResourcesExist
+// -----------------------------------------------------------------------------
+//
+TBool CSipConnection::DoTransportResourcesExist() const
+	{
+	return ( iIcmpReceiver != 0 &&
+			 iServerResolver != 0 &&
+			 iLocalAddrResolver != 0 &&
+			 iRequestQueue != 0 );
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::OpenConnection
+// -----------------------------------------------------------------------------
+//
+TInt CSipConnection::OpenConnection()
+	{
+	return iConnection->OpenConnection( iIapId, iServer );
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::CloseConnection
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::CloseConnection()
+	{
+	if ( iConnection )
+		{
+		iConnection->CloseConnection();
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::ResolveLocalAddress
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::ResolveLocalAddress( TInetAddr& aAddress )
+	{
+	GetLocalAddress( aAddress );
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::StartMonitoringL
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::StartMonitoringL( TInt aError )
+	{
+#ifdef CPPUNIT_TEST
+	aError; // silence warning
+#else
+	// In unit testing hard coded IAPs cannot be expected 
+	// to be valid in all environments. 
+	// Not trying to load monitor plug-in by IAP in unit tests 
+    iNetworkManager.RegisterObserverL( *iStateModel, iIapId, aError );
+#endif
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::StopMonitoring
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::StopMonitoring()
+	{
+	iNetworkManager.Deregister( *iStateModel );
+	}
+	
+// -----------------------------------------------------------------------------
+// CSipConnection::ContinueMonitoring
+// -----------------------------------------------------------------------------
+//
+TBool CSipConnection::ContinueMonitoring( TInt aError )
+	{
+	return iNetworkManager.ContinueMonitoring( *iStateModel, aError );
+	}
+	
+// -----------------------------------------------------------------------------
+// CSipConnection::MonitorConnectionClosure
+// -----------------------------------------------------------------------------
+//	
+TInt CSipConnection::MonitorConnectionClosure()
+    {
+    return iConnection->MonitorConnectionClosure( iServer );
+    }	
+
+// -----------------------------------------------------------------------------
+// CSipConnection::StateModelChanged
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::StateModelChanged( CStateModel::TState aState )
+	{
+	CSIPConnection::TState oldState = iState;
+	SetState( aState );
+	if( oldState != iState )
+		{
+		TRAP_IGNORE( 
+		    iTUNetStatusObserver.ConnectionStateChangedL( iIapId, iState ) )
+		}
+	}
+	
+// -----------------------------------------------------------------------------
+// CSipConnection::Destroy
+// -----------------------------------------------------------------------------
+//	
+void CSipConnection::Destroy()
+	{
+	iOwner.Destroy( iIapId );
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::DetermineConnectionTypeL
+// -----------------------------------------------------------------------------
+//
+TInt CSipConnection::DetermineConnectionTypeL()
+	{
+	TInt bearer = KErrNotFound;
+  CMDBSession* cdb = CMDBSession::NewLC( KCDVersion1_1 ); 
+  cdb->SetAttributeMask( ECDHidden );
+  // Create an iap record
+  CCDIAPRecord* iapRecord = static_cast<CCDIAPRecord*>( 
+              CCDRecordBase::RecordFactoryL( KCDTIdIAPRecord ) );
+  CleanupStack::PushL( iapRecord );
+  iapRecord->SetRecordId( IapId() );
+  iapRecord->LoadL( *cdb );
+  TPtrC bearerType(iapRecord->iBearerType);
+  if(bearerType.CompareF(TPtrC(KCDTypeNameLANBearer)) == 0)
+	bearer =  MSIPConnectionContext::ELanBearer;
+  else if(bearerType.CompareF(TPtrC(KCDTypeNameModemBearer)) == 0)
+	bearer =  MSIPConnectionContext::EModemBearer;
+  CleanupStack::PopAndDestroy( iapRecord );
+  CleanupStack::PopAndDestroy( cdb );
+  return bearer;
+	}
+
+
+
+// -----------------------------------------------------------------------------
+// CSipConnection::State
+// -----------------------------------------------------------------------------
+//	
+CSIPConnection::TState CSipConnection::State()
+	{
+	return iState;
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::SystemStarted
+// -----------------------------------------------------------------------------
+//	
+void CSipConnection::SystemStarted()
+    {
+    iStateModel->EnterState( MStateModel::EInit, KErrNone );
+    }
+
+// -----------------------------------------------------------------------------
+// CSipConnection::CellularUsageAllowed
+// -----------------------------------------------------------------------------
+//	
+
+void CSipConnection::CellularUsageAllowed()
+{
+	if(iWaitingForDataUsage)
+	{
+	iWaitingForDataUsage=EFalse;
+	__SIP_LOG( "CSipConnection::CellularUsageAllowed Execution" )
+    iStateModel->EnterState( MStateModel::EInit, KErrNone );
+	}
+}
+
+
+// -----------------------------------------------------------------------------
+// CSipConnection::TopViaHeader
+// -----------------------------------------------------------------------------
+//
+CSIPViaHeader* CSipConnection::TopViaHeader( CSIPMessage* aMessage )
+	{
+	CSIPViaHeader* via = NULL;
+	if( aMessage->HasHeader( SIPStrings::StringF(SipStrConsts::EViaHeader) ) )
+		{
+		TSglQueIter< CSIPHeaderBase > iter =
+			aMessage->Headers( SIPStrings::StringF(SipStrConsts::EViaHeader) );
+		CSIPHeaderBase* header = iter;
+		via = static_cast< CSIPViaHeader* >( header );
+		}
+	return via;
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::SetState
+// -----------------------------------------------------------------------------
+//	
+void CSipConnection::SetState ( MStateModel::TState aState )
+	{
+	switch( aState )
+		{
+		case MStateModel::EInit:
+			{
+			iState = CSIPConnection::EInit;
+			break;
+			}
+		case MStateModel::EInactiveMonitoring:
+		case MStateModel::EInactiveConnecting:
+			{
+			iState = CSIPConnection::EInactive;
+			break;
+			}
+		case MStateModel::EActiveResolving:
+			{
+			// Does not yet change the current SIP connection state.
+			// The SIP connection state changes with the next state transition.
+			break;	
+			}			
+		case MStateModel::EActiveResolved:
+			{
+			iState = CSIPConnection::EActive;
+			break;
+			}
+		case MStateModel::ESuspended:
+			{
+			iState = CSIPConnection::ESuspended;
+			break;
+			}
+		case MStateModel::EUnavailable:
+		default:
+			{
+			iState = CSIPConnection::EUnavailable;
+			break;
+			}
+		}	
+	}
+	
+// -----------------------------------------------------------------------------
+// CSipConnection::Connection
+// -----------------------------------------------------------------------------
+//
+RConnection& CSipConnection::Connection()
+	{
+	return iConnection->Connection();
+	}	
+
+// -----------------------------------------------------------------------------
+// CSipConnection::NotifyIcmpErrorL
+// -----------------------------------------------------------------------------
+//	
+void CSipConnection::NotifyIcmpErrorL( const TInetAddr& aAddress )
+    {
+    CSipConnectionMgr::TICMPError error = CSipConnectionMgr::ENetUnreachable;
+	iFinder.IcmpErrorL( aAddress, error );
+	CTransportBase* listItem;
+	iListIter.SetToFirst();
+	while ( ( listItem = iListIter++ ) != 0 )
+		{
+		listItem->ICMPErrorL( error, aAddress );
+		}
+    }
+
+// -----------------------------------------------------------------------------
+// CSipConnection::IsConnectionActive
+// -----------------------------------------------------------------------------
+//   
+TBool CSipConnection::IsConnectionActive() const
+    {
+    return ( iState == CSIPConnection::EActive );
+    }
+
+// -----------------------------------------------------------------------------
+// CSipConnection::UpdateURIL
+// -----------------------------------------------------------------------------
+// 
+void CSipConnection::UpdateURIL( 
+    CURIContainer& aURI, 
+    const TInetAddr& aAddress,
+    TUint aProtocol ) const
+    {
+    __ASSERT_ALWAYS( aURI.IsSIPURI(), User::Leave( KErrSIPInvalidURIType ) );
+	
+	CSIPURI& uri = *aURI.SIPURI();
+	
+	RStringF transport;
+    if ( aProtocol == KProtocolInetTcp )
+        {
+        transport = SIPStrings::StringF( SipStrConsts::ETCP );
+        }
+    else if ( aProtocol == KProtocolTls )
+        {
+        transport = SIPStrings::StringF( SipStrConsts::ETLS );
+        }
+    else
+        {
+        User::Leave( KErrArgument );
+        }
+	
+    uri.SetParamL( SIPStrings::StringF( SipStrConsts::ETransport ), transport );
+
+    uri.HostPort().SetPort( aAddress.Port() );
+    
+    HBufC8* addressText = CTransport::ConvertInetAddrToTextL( aAddress );
+    CleanupStack::PushL( addressText );
+    uri.HostPort().SetHostL( *addressText );
+    CleanupStack::PopAndDestroy( addressText );
+    }
+    
+// -----------------------------------------------------------------------------
+// CSipConnection::CSipConnection
+// -----------------------------------------------------------------------------
+//
+CSipConnection::CSipConnection( MTransactionFinder& aFinder,
+								MServerTaFactory& aTaFactory,
+								MTimerManager& aTimer,
+								TUint aTOne,
+								const TSIPTransportParams& aParams,
+								RSocketServ& aServer,
+								MSigCompController& aSigCompHandler,
+								MConnectionStateObserver& aTUNetStatusObserver,
+								CNetworkManager& aNetworkManager,
+								MSipConnectionOwner& aOwner,
+								CNetworkInfo& aNetworkInfo,
+								CSIPNATTraversalController& aNATTraversal )
+	: iFinder( aFinder ),
+	  iTaFactory( aTaFactory ),
+	  iTUNetStatusObserver( aTUNetStatusObserver ),
+	  iSigCompHandler( aSigCompHandler ),
+	  iServer( aServer ),
+	  iList( CTransportBase::iOffset ),
+	  iListIter( iList ),
+	  iTcpSenderList( CTcpResponseSender::iSenderOffset ),
+	  iTcpSenderListIter( iTcpSenderList ),
+	  iTOne( aTOne ),
+	  iNetworkManager( aNetworkManager ),
+	  iTimer( aTimer ),
+	  iOwner( aOwner ),
+	  iIapId( aParams.IapId() ),
+	  iState( CSIPConnection::EInit ),
+	  iNetworkInfo( aNetworkInfo ),
+	  iNATTraversal( aNATTraversal )
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::~CSipConnection
+// -----------------------------------------------------------------------------
+//
+CSipConnection::~CSipConnection()
+	{	
+	delete iSettingsList;
+	iNetworkManager.Deregister( *iStateModel );
+	delete iStateModel;
+     // Use scope operator for keeping PC-Lint happy
+	CSipConnection::ReleaseTransportResources( ETrue );
+	delete iConnection;	
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CSipConnection::ConstructL()
+	{	
+	iWaitingForDataUsage = EFalse;
+	iSettingsList = COwnerSettingsList::NewL();	
+	iStateModel = CStateModel::NewL( *this, iTimer );
+	iConnection = CConnectionContainer::NewL( *iStateModel );	
+    if ( iOwner.IsSystemStarted())
+		{ 
+		if ((ConnectionType() == MSIPConnectionContext::EModemBearer) && (!iOwner.IsCellularDataUsageAllowed()) )
+			{
+			iWaitingForDataUsage = ETrue;
+			__SIP_LOG( "CSipConnection::ConstructL() is blocking Connection Start Up..." )
+			return;
+			}
+		else
+			{
+			__SIP_LOG( "CSipConnection::ConstructL() is Allowing Connection Start Up..." )
+	        iStateModel->EnterState( MStateModel::EInit, KErrNone );
+			}
+       	}
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::ConnectionError
+// -----------------------------------------------------------------------------
+//
+TInt CSipConnection::ConnectionError()
+	{
+	return iStateModel->Error();
+	}
+
+// -----------------------------------------------------------------------------
+// CSipConnection::ConnectionType()
+// -----------------------------------------------------------------------------
+//
+TInt CSipConnection::ConnectionType()
+	{
+	TInt type = MSIPConnectionContext::EModemBearer;
+	TRAP_IGNORE( type = DetermineConnectionTypeL( ) )
+	return type;
+	}
+