--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SIP/ConnectionMgr/src/CTransportUdp.cpp Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,787 @@
+// Copyright (c) 2002-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 : CTransportUdp.cpp
+// Part of : ConnectionMgr
+// Version : SIP/4.0
+//
+
+
+
+
+#include "CTransportUdp.h"
+#include "CSipConnection.h"
+#include "CErrorHandler.h"
+#include "CReceiver.h"
+#include "CSenderUdp.h"
+#include "CSIPServerResolver.h"
+#include "sipviaheader.h"
+#include "siphostport.h"
+#include "sipmessage.h"
+#include "sipresponse.h"
+#include "Lwtimer.h"
+#include "SipLogs.h"
+#include "CResHandler.h"
+#include "utf.h"
+#include "CommonConsts.h"
+#include "sipstrings.h"
+#include "sipstrconsts.h"
+#include "siperr.h"
+#include "NetworkInfo.h"
+#include "COwnerSettingsList.h"
+#include "CSocketContainer.h"
+#include "MSocketUsagePermissionObserver.h"
+#include <sipnattraversalcontroller.h>
+
+
+const TInt KTransportUsersGranularity = 2;
+
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::NewL
+// -----------------------------------------------------------------------------
+//
+CTransportUdp* CTransportUdp::NewL(
+ RSocketServ& aServer,
+ TUint aPort,
+ MTransactionFinder& aFinder,
+ MServerTaFactory& aTaFactory,
+ MTransportOwner& aTransportOwner,
+ MTimerManager& aTimerManager,
+ CSIPServerResolver& aServerResolver,
+ RConnection& aConnection,
+ MSigCompController& aSigCompHandler,
+ TUint aICMPErrorWaitTime,
+ CNetworkInfo& aNetworkInfo,
+ COwnerSettingsList& aSettingsList,
+ const TSIPTransportParams& aTransportParams,
+ CSIPNATTraversalController& aNATTraversal,
+ TBool aOnlyForReceiving )
+ {
+ CTransportUdp* self = NewLC( aServer, aPort, aFinder, aTaFactory,
+ aTransportOwner, aTimerManager,
+ aServerResolver, aConnection, aSigCompHandler,
+ aICMPErrorWaitTime, aNetworkInfo,
+ aSettingsList, aTransportParams,
+ aNATTraversal, aOnlyForReceiving );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::NewLC
+// -----------------------------------------------------------------------------
+//
+CTransportUdp* CTransportUdp::NewLC(
+ RSocketServ& aServer,
+ TUint aPort,
+ MTransactionFinder& aFinder,
+ MServerTaFactory& aTaFactory,
+ MTransportOwner& aTransportOwner,
+ MTimerManager& aTimerManager,
+ CSIPServerResolver& aServerResolver,
+ RConnection& aConnection,
+ MSigCompController& aSigCompHandler,
+ TUint aICMPErrorWaitTime,
+ CNetworkInfo& aNetworkInfo,
+ COwnerSettingsList& aSettingsList,
+ const TSIPTransportParams& aTransportParams,
+ CSIPNATTraversalController& aNATTraversal,
+ TBool aOnlyForReceiving )
+ {
+ CTransportUdp* self = new ( ELeave ) CTransportUdp( aServer,
+ aPort,
+ aFinder,
+ aTaFactory,
+ aTransportOwner,
+ aTimerManager,
+ aServerResolver,
+ aConnection,
+ aSigCompHandler,
+ aICMPErrorWaitTime,
+ aNetworkInfo,
+ aSettingsList,
+ aTransportParams,
+ aNATTraversal,
+ aOnlyForReceiving );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::CTransportUdp
+// -----------------------------------------------------------------------------
+//
+CTransportUdp::CTransportUdp(
+ RSocketServ& aServer,
+ TUint aPort,
+ MTransactionFinder& aFinder,
+ MServerTaFactory& aTaFactory,
+ MTransportOwner& aTransportOwner,
+ MTimerManager& aTimerManager,
+ CSIPServerResolver& aServerResolver,
+ RConnection& aConnection,
+ MSigCompController& aSigCompHandler,
+ TUint aICMPErrorWaitTime,
+ CNetworkInfo& aNetworkInfo,
+ COwnerSettingsList& aSettingsList,
+ const TSIPTransportParams& aTransportParams,
+ CSIPNATTraversalController& aNATTraversal,
+ TBool aOnlyForReceiving )
+ :
+ CTransport( aFinder, aTaFactory, aTransportOwner, aServerResolver,
+ aSigCompHandler, aTransportParams, aNetworkInfo,
+ aSettingsList, aNATTraversal ),
+ iSocketServ( &aServer ),
+ iConnection( &aConnection ),
+ iSourcePort( aPort ),
+ iTimerManager( aTimerManager ),
+ iList( CResponseHandler::iOffset ),
+ iListIter( iList ),
+ iICMPErrorWaitTime( aICMPErrorWaitTime ),
+ iTransportUsers( KTransportUsersGranularity ),
+ iOnlyForReceiving( aOnlyForReceiving ),
+ iIsSending( EFalse )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::ConstructL()
+ {
+ iErrorHandler = CTransportErrorHandler::NewL( *this );
+
+ RefreshSocketContainerL( KAfInet );
+ RefreshSocketContainerL( KAfInet6 );
+
+ iSender = CSenderUdp::NewL( *this, iSettingsList );
+
+ iTransportUsers.AppendL( iTransportParams.TransportId() );
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::~CTransportUdp
+// -----------------------------------------------------------------------------
+//
+CTransportUdp::~CTransportUdp()
+ {
+ if ( iSocketUsagePermissionObserver )
+ {
+ iSocketUsagePermissionObserver->UsagePermissionChanged( iIPv4Socket, EFalse );
+ iSocketUsagePermissionObserver->UsagePermissionChanged( iIPv6Socket, EFalse );
+ }
+
+ iNATTraversal.SocketIdle( EFalse, iIPv4Socket );
+ iNATTraversal.SocketIdle( EFalse, iIPv6Socket );
+
+ CResponseHandler* listItem;
+ iListIter.SetToFirst();
+ while ( ( listItem = iListIter++ ) != 0 )
+ {
+ iList.Remove( *listItem );
+ delete listItem;
+ }
+ delete iErrorHandler;
+ delete iIPv4Receiver;
+ delete iIPv6Receiver;
+ delete iSender;
+ delete iIPv4SocketContainer;
+ delete iIPv6SocketContainer;
+ iNATTraversal.SocketIdle( EFalse, iIPv4Socket );
+ iIPv4Socket.Close();
+ iNATTraversal.SocketIdle( EFalse, iIPv6Socket );
+ iIPv6Socket.Close();
+ iTransportUsers.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::Handle
+// -----------------------------------------------------------------------------
+//
+TBool CTransportUdp::Handle( TUint32 aTransportId )
+ {
+ // Only interested about "protected" transports
+ return ( ( aTransportId > 0 ) &&
+ ( iTransportUsers.Find( aTransportId ) != KErrNotFound ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::HandleMessage
+// -----------------------------------------------------------------------------
+//
+TBool CTransportUdp::HandleMessage( const TSIPTransportParams& aParams,
+ RStringF aProtocol,
+ const TInetAddr& /*aRemoteAddr*/,
+ TUint aLocalPort,
+ TBool aIsStrict )
+ {
+ // If not strict comparison, receiveonly mode has no significance
+ return ( aProtocol == SIPStrings::StringF( SipStrConsts::EUDP ) &&
+ Match( aParams ) &&
+ ( aLocalPort == 0 || iSourcePort == aLocalPort ) &&
+ ( !aIsStrict || !iOnlyForReceiving ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::ResetSocketL
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::ResetSocketL()
+ {
+ iIPv4Socket.Close();
+ CSocketContainer* tmp = CreateSocketContainerL( KAfInet, iIPv4Socket );
+ delete iIPv4SocketContainer;
+ iIPv4SocketContainer = tmp;
+
+ iIPv6Socket.Close();
+ tmp = CreateSocketContainerL( KAfInet6, iIPv6Socket );
+ delete iIPv6SocketContainer;
+ iIPv6SocketContainer = tmp;
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::StopL
+// -----------------------------------------------------------------------------
+//
+TBool CTransportUdp::StopL()
+ {
+ if ( iIPv4Receiver )
+ {
+ iIPv4Receiver->Cancel();
+ }
+ if ( iIPv6Receiver )
+ {
+ iIPv6Receiver->Cancel();
+ }
+ iSender->Cancel();
+
+ // If there's binding observers, notify that old socket
+ // cannot be used anymore
+ return NotifyFlowFailure();
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::ContinueL
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::ContinueL()
+ {
+ WaitL();
+ iSender->SendNextL();
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::SourcePort
+// -----------------------------------------------------------------------------
+//
+TUint CTransportUdp::SourcePort()
+ {
+ return iSourcePort;
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::WaitL
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::WaitL()
+ {
+ if ( iIPv4Receiver )
+ {
+ iIPv4Receiver->Listen();
+ }
+ if ( iIPv6Receiver )
+ {
+ iIPv6Receiver->Listen();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::SendToNetL
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::SendToNetL( const TSIPTransportParams& aParams,
+ const TInetAddr& aAddress,
+ CSIPMessage& aMessage,
+ TBool aForceUDP,
+ TUint aOrigTransport,
+ TRequestStatus &aStatus )
+ {
+ RefreshSocketContainerL( CSender::IpAddrType( aAddress ) );
+ HandleMixedAddressFamilysL( aMessage, aAddress );
+
+ iSender->SendL(
+ aParams,
+ aMessage,
+ aAddress,
+ aOrigTransport,
+ aStatus,
+ EFalse,
+ aForceUDP );
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::SendToNetL
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::SendToNetL( const TSIPTransportParams& aParams,
+ const TInetAddr& aAddress,
+ CSIPMessage& aMessage,
+ TRequestStatus &aStatus )
+ {
+ RefreshSocketContainerL( CSender::IpAddrType( aAddress ) );
+ HandleMixedAddressFamilysL( aMessage, aAddress );
+
+ iSender->SendL(
+ aParams,
+ aMessage,
+ aAddress,
+ 0,
+ aStatus,
+ EFalse,
+ EFalse );
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::SendToNetL
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::SendToNetL( const TSIPTransportParams& aParams,
+ const TInetAddr& aAddress,
+ TTransactionId aId,
+ CSIPMessage& aMessage,
+ TRequestStatus &aStatus )
+ {
+ RefreshSocketContainerL( CSender::IpAddrType( aAddress ) );
+ HandleMixedAddressFamilysL( aMessage, aAddress );
+
+ CResponseHandler* listItem = 0;
+ iListIter.SetToFirst();
+ while ( ( listItem = iListIter++ ) != 0 )
+ {
+ if(listItem->Handle( aId ) )
+ {
+ listItem->SendL( aParams,
+ static_cast<CSIPResponse&>( aMessage ),
+ aAddress,
+ aStatus );
+ return;
+ }
+ }
+ CResponseHandler* responsehandler =
+ CResponseHandler::NewL( *this, iTimerManager, *iServerResolver, aId,
+ iICMPErrorWaitTime );
+ iList.AddLast( *responsehandler );
+ responsehandler->SendL( aParams,
+ static_cast<CSIPResponse&>( aMessage ),
+ aAddress,
+ aStatus);
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::CancelSend
+// -----------------------------------------------------------------------------
+//
+TBool CTransportUdp::CancelSend( TRequestStatus& aStatus )
+ {
+ return iSender->FindAndCancel( aStatus );
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::CancelAllRequests
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::CancelAllRequests( CSIPConnection::TState aReason )
+ {
+ iSender->CancelAllRequests( aReason );
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::CancelResponseSend
+// -----------------------------------------------------------------------------
+//
+TBool CTransportUdp::CancelResponseSend(
+ TTransactionId aId,
+ TBool aCancelAlso2xxResponses )
+ {
+ CResponseHandler* listItem = 0;
+ iListIter.SetToFirst();
+ while ( ( listItem = iListIter++ ) != 0 )
+ {
+ if ( listItem->Handle( aId ) )
+ {
+ return listItem->CancelAll( aId, aCancelAlso2xxResponses );
+ }
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::IsWaiting
+// -----------------------------------------------------------------------------
+//
+TBool CTransportUdp::IsWaiting( TUint aProtocol, TUint aPort )
+ {
+ return ( aPort == SourcePort() && aProtocol == KProtocolInetUdp );
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::SocketContainer
+// -----------------------------------------------------------------------------
+//
+CSocketContainer& CTransportUdp::SocketContainer()
+ {
+ if ( iIPv6SocketContainer )
+ {
+ return *iIPv6SocketContainer;
+ }
+ return *iIPv4SocketContainer;
+ }
+// -----------------------------------------------------------------------------
+// CTransportUdp::SocketContainer
+// -----------------------------------------------------------------------------
+//
+CSocketContainer* CTransportUdp::SocketContainer( TUint aIPAddrFamily )
+ {
+ if ( aIPAddrFamily == KAfInet )
+ {
+ if ( iIPv4SocketContainer )
+ {
+ return iIPv4SocketContainer;
+ }
+ return iIPv6SocketContainer;
+ }
+ else
+ {
+ if ( iIPv6SocketContainer )
+ {
+ return iIPv6SocketContainer;
+ }
+ }
+ return NULL; // Only IPv6 socket can be used for sending to a IPv6 address
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::ICMPErrorL
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::ICMPErrorL( CSipConnectionMgr::TICMPError aICMPError,
+ const TInetAddr& aSourceAddr )
+ {
+ CResponseHandler* listItem = 0;
+ iListIter.SetToFirst();
+ while ( ( listItem = iListIter++ ) != 0 )
+ {
+ listItem->ICMPErrorL( aICMPError, aSourceAddr );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::RemoveResHandler
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::RemoveResHandler( CResponseHandler* aHandler )
+ {
+ if ( !iList.IsEmpty() )
+ {
+ iList.Remove( *aHandler );
+ delete aHandler;
+ __SIP_LOG( "CResHandler removed" )
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::ConnectionOpenL
+// -----------------------------------------------------------------------------
+//
+TBool CTransportUdp::ConnectionOpenL()
+ {
+ User::Leave( KErrNotSupported );
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::DisconnectedL
+// -----------------------------------------------------------------------------
+//
+TBool CTransportUdp::DisconnectedL()
+ {
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::GetSocketContainerL
+// -----------------------------------------------------------------------------
+//
+CSocketContainer& CTransportUdp::GetSocketContainerL(
+ const TInetAddr& aRemoteAddr )
+ {
+ CSocketContainer* socketContainer =
+ SocketContainer( CSender::IpAddrType( aRemoteAddr ) );
+ __ASSERT_ALWAYS( socketContainer, User::Leave( KErrNotFound ) );
+ return *socketContainer;
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::InformSendingStatus
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::InformSendingStatus( const TInetAddr& /*aRemoteAddr*/ )
+ {
+ __SIP_INT_LOG2( "CTransportUdp::InformSendingStatus (socket IPv4,sending)",
+ iIPv4Socket.SubSessionHandle(), iIsSending )
+
+ __SIP_INT_LOG2( "CTransportUdp::InformSendingStatus (socket IPv6,sending)",
+ iIPv6Socket.SubSessionHandle(), iIsSending )
+
+ iNATTraversal.SocketIdle( !iIsSending, iIPv4Socket );
+ iNATTraversal.SocketIdle( !iIsSending, iIPv6Socket );
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::Sender
+// -----------------------------------------------------------------------------
+//
+CSender* CTransportUdp::Sender( const TSIPTransportParams& aParams,
+ TUint aProtocol,
+ const TInetAddr& /*aRemoteAddr*/)
+ {
+ if ( aProtocol == Protocol() && Match( aParams ) )
+ {
+ return iSender;
+ }
+ return 0;
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::Remove
+// -----------------------------------------------------------------------------
+//
+TBool CTransportUdp::Remove( TUint32 aTransportId )
+ {
+ TInt index = iTransportUsers.Find( aTransportId );
+ if ( index != KErrNotFound )
+ {
+ iTransportUsers.Remove( index );
+ iTransportUsers.Compress();
+ }
+
+ // If no more transport users left and this is "protected" transport,
+ // the whole transport can be removed
+ return ( iTransportUsers.Count() == 0 && IsReservedTransport() );
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::AddUserL
+// -----------------------------------------------------------------------------
+//
+TBool CTransportUdp::AddUserL(
+ const TSIPTransportParams& aParams,
+ TUint aReceivePort )
+ {
+ __ASSERT_ALWAYS( aReceivePort == iSourcePort, User::Leave( KErrArgument ) );
+
+ // Don't allow duplicate entries
+ User::LeaveIfError( iTransportUsers.InsertInOrder( aParams.TransportId() ) );
+
+ return ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::AcquireUdpSocket
+// -----------------------------------------------------------------------------
+//
+RSocket* CTransportUdp::AcquireUdpSocket(
+ MSocketUsagePermissionObserver* aObserver,
+ const TInetAddr& aRemoteAddr,
+ TBool& aPermissionToUse )
+ {
+ aPermissionToUse = EFalse;
+
+ // If observer is not provided, caller cannot use the socket
+ if ( aObserver )
+ {
+ // If sender is active, we cannot give permission until the
+ // send is complete.
+ aPermissionToUse = !iSender->IsActive();
+
+ // When we give permission for the caller to use the socket,
+ // sender cannot send until UdpSocketReleased is called.
+ iSender->SetSendPermission( !aPermissionToUse );
+
+ iSocketUsagePermissionObserver = aObserver;
+ }
+
+ RSocket* socket = NULL;
+ if ( aRemoteAddr.Address() && iIPv4SocketContainer )
+ {
+ socket = &iIPv4Socket;
+ }
+ else
+ {
+ socket = &iIPv6Socket;
+ }
+
+ return socket;
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::UdpSocketReleased
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::UdpSocketReleased(
+ MSocketUsagePermissionObserver* aObserver,
+ RSocket& aSocket )
+ {
+ if ( aObserver &&
+ ( iIPv4Socket.SubSessionHandle() == aSocket.SubSessionHandle() ||
+ iIPv6Socket.SubSessionHandle() == aSocket.SubSessionHandle() ) )
+ {
+ iSocketUsagePermissionObserver = 0;
+ iSender->SetSendPermission( ETrue );
+ TRAP_IGNORE( iSender->SendNextL() )
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::Remove
+// -----------------------------------------------------------------------------
+//
+TInt CTransportUdp::Remove()
+ {
+ return iTransportOwner->RemoveTransport( this );
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::IapId
+// -----------------------------------------------------------------------------
+//
+TUint32 CTransportUdp::IapId()
+ {
+ return iTransportOwner->IapId();
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::Sending
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::Sending( TBool aIsSending )
+ {
+ __SIP_INT_LOG2( "CTransportUdp::Sending (socket IPv4,sending)",
+ iIPv4Socket.SubSessionHandle(), iIsSending )
+
+ __SIP_INT_LOG2( "CTransportUdp::Sending (socket IPv6,sending)",
+ iIPv6Socket.SubSessionHandle(), iIsSending )
+
+ iIsSending = aIsSending;
+
+ if ( iSocketUsagePermissionObserver )
+ {
+ iSocketUsagePermissionObserver->UsagePermissionChanged( iIPv4Socket,
+ !iIsSending );
+ iSocketUsagePermissionObserver->UsagePermissionChanged( iIPv6Socket,
+ !iIsSending );
+ }
+
+ iNATTraversal.SocketIdle( !iIsSending, iIPv4Socket );
+ iNATTraversal.SocketIdle( !iIsSending, iIPv6Socket );
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::ReRouteL
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::ReRouteL( TUint aProtocol,
+ COutgoingData* aData )
+ {
+ iTransportOwner->ReRouteL( aProtocol, aData );
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::ReceivedDataL
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::ReceivedDataL( HBufC8* aData,
+ const TInetAddr& aRemoteAddr,
+ TBool aCompressed )
+ {
+ RecvL( aData, aRemoteAddr, aCompressed );
+ }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::SigCompHandler
+// -----------------------------------------------------------------------------
+//
+MSigCompController* CTransportUdp::SigCompHandler()
+ {
+ return SigCompressionHandler();
+ }
+// -----------------------------------------------------------------------------
+// CTransportUdp::RefreshSocketContainerL
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::RefreshSocketContainerL( TUint aFamily )
+ {
+ if ( aFamily == KAfInet && !iIPv4SocketContainer )
+ {
+ iIPv4SocketContainer = CreateSocketContainerL( KAfInet, iIPv4Socket );
+ if ( iIPv4SocketContainer )
+ {
+ iIPv4Receiver = CReceiver::NewL( *this, KAfInet );
+ iIPv4Receiver->Listen();
+ }
+ }
+ if ( aFamily == KAfInet6 && !iIPv6SocketContainer )
+ {
+ iIPv6SocketContainer = CreateSocketContainerL( KAfInet6, iIPv6Socket );
+ if ( iIPv6SocketContainer )
+ {
+ iIPv6Receiver = CReceiver::NewL( *this, KAfInet6 );
+ iIPv6Receiver->Listen();
+ }
+ }
+ }
+// -----------------------------------------------------------------------------
+// CTransportUdp::CreateSocketContainerL
+// -----------------------------------------------------------------------------
+//
+CSocketContainer* CTransportUdp::CreateSocketContainerL(
+ TUint aFamily,
+ RSocket& aSocket )
+ {
+ CSocketContainer* socketContainer( NULL );
+ TInetAddr addr;
+ if ( iTransportOwner->GetLocalIPAddr( aFamily, addr ) )
+ {
+ User::LeaveIfError(
+ aSocket.Open( *iSocketServ, KAfInet, KSockDatagram,
+ KProtocolInetUdp, *iConnection ) );
+ socketContainer = CSocketContainer::NewLC( aSocket );
+ aSocket.SetOpt( KSoReuseAddr, KSolInetIp, 1 );
+ addr.SetPort( iSourcePort );
+ addr.SetFamily( aFamily );
+ TInt err = aSocket.Bind( addr );
+ if ( err == KErrInUse )
+ {
+ User::Leave( KErrSIPTransportFailure );
+ }
+ else
+ {
+ User::LeaveIfError( err );
+ }
+ CleanupStack::Pop( socketContainer );
+ }
+ return socketContainer;
+ }