realtimenetprots/sipfw/SIP/ConnectionMgr/src/COutgoingRequestQueue.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Name        : COutgoingRequestQueue.cpp
       
    15 // Part of     : ConnectionMgr
       
    16 // Version     : SIP/5.0
       
    17 //
       
    18 
       
    19 
       
    20 
       
    21 #include "COutgoingRequestQueue.h"
       
    22 #include "MOutgoingRequestQueueContext.h"
       
    23 #include "CTransport.h"
       
    24 #include "siprequest.h"
       
    25 #include "sipstrings.h"
       
    26 #include "sipstrconsts.h"
       
    27 #include "sipcontactheader.h"
       
    28 #include "sipviaheader.h"
       
    29 #include "siptoheader.h"
       
    30 #include "sipfromheader.h"
       
    31 #include "uricontainer.h"
       
    32 #include "sipuri.h"
       
    33 #include "sipaddress.h"
       
    34 #include "siphostport.h"
       
    35 #include "TSIPTransportParams.h"
       
    36 #include "sipstrings.h"
       
    37 #include "sipstrconsts.h"
       
    38 #include "SIPHeaderLookup.h"
       
    39 #include "siperr.h"
       
    40 #include <sipnattraversalcontroller.h> 
       
    41 
       
    42 const TInt KRequestQueueGranularity = 4;
       
    43     
       
    44 // -----------------------------------------------------------------------------
       
    45 // COutgoingRequestQueue::NewLC
       
    46 // -----------------------------------------------------------------------------
       
    47 //
       
    48 COutgoingRequestQueue* COutgoingRequestQueue::NewL( 
       
    49     MOutgoingRequestQueueContext& aContext,
       
    50     CSIPNATTraversalController& aNATTraversal,
       
    51     RConnection& aConnection,
       
    52     TUint32 aIapId )
       
    53     {
       
    54     COutgoingRequestQueue* self = 
       
    55         new ( ELeave ) COutgoingRequestQueue( aContext, 
       
    56                                               aNATTraversal, 
       
    57                                               aConnection, 
       
    58                                               aIapId );
       
    59     
       
    60     CleanupStack::PushL( self );
       
    61     self->ConstructL();
       
    62     CleanupStack::Pop( self );
       
    63     return self;
       
    64     }
       
    65     
       
    66 // -----------------------------------------------------------------------------
       
    67 // COutgoingRequestQueue::~COutgoingRequestQueue
       
    68 // -----------------------------------------------------------------------------
       
    69 //
       
    70 COutgoingRequestQueue::~COutgoingRequestQueue()
       
    71     {
       
    72     iNATTraversal.FreeResources( iIapId );
       
    73     iRequestQueue.Close();
       
    74     iStrNATTraversalRequired.Close();
       
    75     }
       
    76 
       
    77 // -----------------------------------------------------------------------------
       
    78 // COutgoingRequestQueue::RequestComplete
       
    79 // From MSIPNATTraversalRequestObserver
       
    80 // -----------------------------------------------------------------------------
       
    81 //
       
    82 void COutgoingRequestQueue::RequestComplete( 
       
    83     TUint32 aRequestId, 
       
    84     TInt aCompletionCode )
       
    85     {
       
    86     TInt index = FindRequestQueueItemIndex( aRequestId );
       
    87     if ( index != KErrNotFound )
       
    88         {
       
    89         Complete( iRequestQueue[ index ], aCompletionCode, EFalse );
       
    90         iRequestQueue.Remove( index );
       
    91         iRequestQueue.Compress();
       
    92         }  
       
    93     ActivatePendingRequests();
       
    94     }
       
    95 
       
    96 // -----------------------------------------------------------------------------
       
    97 // COutgoingRequestQueue::PublicAddrResolved
       
    98 // From MSIPNATTraversalRequestObserver
       
    99 // -----------------------------------------------------------------------------
       
   100 //		    
       
   101 void COutgoingRequestQueue::PublicAddrResolved( 
       
   102     TUint32 aRequestId, 
       
   103     const TInetAddr& aPublicAddr )
       
   104     {
       
   105     TInt index = FindRequestQueueItemIndex( aRequestId );
       
   106     if ( index != KErrNotFound )
       
   107         {
       
   108         Update( iRequestQueue[ index ], aPublicAddr );
       
   109         iRequestQueue.Remove( index );
       
   110         iRequestQueue.Compress();
       
   111         }
       
   112     ActivatePendingRequests();
       
   113     }
       
   114 
       
   115 // -----------------------------------------------------------------------------
       
   116 // COutgoingRequestQueue::UsagePermissionChanged
       
   117 // From MSocketUsagePermissionObserver
       
   118 // -----------------------------------------------------------------------------
       
   119 //    
       
   120 void COutgoingRequestQueue::UsagePermissionChanged( 
       
   121     RSocket& aSocket, 
       
   122     TBool aPermissionToUse )
       
   123     {
       
   124     TInt lastIndex( iRequestQueue.Count() - 1 );
       
   125     for ( TInt i = lastIndex; i >= 0; i-- )
       
   126         {
       
   127         TOutgoingRequestQueueItem& item = iRequestQueue[ i ];
       
   128         if ( item.Match( aSocket ) )
       
   129             {
       
   130             // May lead to removal of the item
       
   131             HandleUsagePermissionChange( item, aPermissionToUse );
       
   132             }
       
   133         }
       
   134     ActivatePendingRequests();
       
   135     }
       
   136 
       
   137 // -----------------------------------------------------------------------------
       
   138 // COutgoingRequestQueue::NATTraverseL
       
   139 // -----------------------------------------------------------------------------
       
   140 //	
       
   141 void COutgoingRequestQueue::NATTraverseL( 
       
   142     const TSIPTransportParams& aParams,
       
   143     CSIPRequest& aRequest,
       
   144     TBool aForceUDP,
       
   145 	const TInetAddr& aAddr,
       
   146 	const CUri8* aOutboundProxy,
       
   147 	TUint aOrigTransport,
       
   148 	TRequestStatus &aStatus,
       
   149 	const TInetAddr& aLocalAddr )
       
   150     {
       
   151     HBufC8* localAddrBuf = CTransport::ConvertInetAddrToTextL( aLocalAddr );
       
   152 	CleanupStack::PushL( localAddrBuf );
       
   153     TUint localPort = ContactPortL( aRequest, *localAddrBuf );
       
   154     CleanupStack::PopAndDestroy( localAddrBuf );    
       
   155     
       
   156     if ( aRequest.Method() == SIPStrings::StringF( SipStrConsts::ERegister ) &&
       
   157          aRequest.To()->HasParam( iStrNATTraversalRequired ) &&
       
   158          !aLocalAddr.IsUnspecified() ) //Nat Traversal for both IPv6 and IPv4 addresses.
       
   159         {
       
   160         RemoveNATTraversalParameter( aRequest );
       
   161         TBool permissionToUse( EFalse );
       
   162         iLocalAddr = aLocalAddr;
       
   163         RSocket& udpSocket = iContext.GetUdpSocketL( aParams, 
       
   164                                                      aAddr, 
       
   165                                                      localPort, 
       
   166                                                      this, 
       
   167                                                      permissionToUse ); 
       
   168     
       
   169         TOutgoingRequestQueueItem queueItem( aParams, 
       
   170                                              aRequest, 
       
   171                                              aForceUDP,
       
   172                                              aAddr, 
       
   173                                              localPort,
       
   174                                              aOutboundProxy,
       
   175                                              aOrigTransport,
       
   176                                              aStatus,
       
   177                                              udpSocket,
       
   178                                              permissionToUse );
       
   179     
       
   180         // If there's already active request for this particular UDP socket,
       
   181         // request cannot be activated before existing request has completed.   
       
   182         if ( permissionToUse && !HasRequestForSocket( udpSocket, EFalse ) )
       
   183             {
       
   184             IssueRequestL( queueItem );
       
   185             }                                                  
       
   186                            
       
   187         iRequestQueue.AppendL( queueItem );
       
   188         
       
   189         // Request status has to be set to pending before going to async.
       
   190         // Set it when this synchronous execution path cannot leave anymore. 
       
   191         aStatus = KRequestPending;        
       
   192         }
       
   193     else
       
   194         {
       
   195         iNATTraversal.UpdateNextHop( 
       
   196             aAddr, 
       
   197             const_cast<TSIPTransportParams&>( aParams ).NATBindingObserver() );
       
   198 
       
   199         iContext.ContinueSendToTransportL( aParams,
       
   200                                            aRequest, 
       
   201                                            aForceUDP,
       
   202                                            aAddr,
       
   203                                            localPort,
       
   204                                            aOrigTransport,
       
   205                                            aStatus,
       
   206                                            EFalse );
       
   207         }
       
   208     }
       
   209 
       
   210 // -----------------------------------------------------------------------------
       
   211 // COutgoingRequestQueue::FreeResources
       
   212 // -----------------------------------------------------------------------------
       
   213 //    
       
   214 void COutgoingRequestQueue::FreeResources( 
       
   215     MSIPNATBindingObserver& aSIPNATBindingObserver )
       
   216     {
       
   217     iNATTraversal.FreeResources( aSIPNATBindingObserver );
       
   218     }
       
   219 
       
   220 // -----------------------------------------------------------------------------
       
   221 // COutgoingRequestQueue::CancelSend
       
   222 // -----------------------------------------------------------------------------
       
   223 //     
       
   224 TBool COutgoingRequestQueue::CancelSend( TRequestStatus& aStatus )
       
   225     {
       
   226     for ( TInt i = 0; i < iRequestQueue.Count(); i++ )
       
   227         {
       
   228         TOutgoingRequestQueueItem& item = iRequestQueue[ i ];
       
   229         if ( item.Match( aStatus ) )
       
   230             {
       
   231             iNATTraversal.Cancel( item.RequestId() );
       
   232             Complete( item, KErrSIPTransportFailure, EFalse );
       
   233             iRequestQueue.Remove( i );
       
   234             iRequestQueue.Compress();
       
   235             return ETrue;
       
   236             }
       
   237         }
       
   238     return EFalse;
       
   239     }
       
   240 
       
   241 // -----------------------------------------------------------------------------
       
   242 // COutgoingRequestQueue::Update
       
   243 // -----------------------------------------------------------------------------
       
   244 //
       
   245 void COutgoingRequestQueue::Update( 
       
   246     TOutgoingRequestQueueItem& aItem, 
       
   247     const TInetAddr& aPublicAddr )
       
   248     {
       
   249     TRAPD( err, UpdateHeadersL( aItem, iLocalAddr, aPublicAddr ) );
       
   250     Complete( aItem, err, ETrue );
       
   251     }
       
   252     
       
   253 // -----------------------------------------------------------------------------
       
   254 // COutgoingRequestQueue::Complete
       
   255 // -----------------------------------------------------------------------------
       
   256 //
       
   257 void COutgoingRequestQueue::Complete( 
       
   258     TOutgoingRequestQueueItem& aItem, 
       
   259     TInt aCompletionCode,
       
   260     TBool aPublicAddrResolved )
       
   261     {     
       
   262     if ( !HasRequestForSocket( aItem.Socket(), ETrue ) )
       
   263         {
       
   264         // Notify if no pending requests exists for the socket
       
   265         iContext.UdpSocketFree( aItem.Params(), 
       
   266                                 aItem.Addr(), 
       
   267                                 aItem.LocalPort(), 
       
   268                                 this,
       
   269                                 aItem.Socket() );
       
   270         }
       
   271     
       
   272     if ( !aCompletionCode )
       
   273         {
       
   274         TRAP( aCompletionCode,
       
   275               iContext.ContinueSendToTransportL( aItem.Params(),
       
   276                                                  aItem.Request(), 
       
   277                                                  aItem.ForceUDP(),
       
   278                                                  aItem.Addr(),
       
   279                                                  aItem.LocalPort(),
       
   280                                                  aItem.OrigTransport(),
       
   281                                                  aItem.Status(),
       
   282                                                  aPublicAddrResolved ) );
       
   283         }
       
   284         
       
   285     if ( aCompletionCode )
       
   286         {
       
   287         iContext.RequestFailed( aItem.Status(), aCompletionCode );
       
   288         }
       
   289     }
       
   290     
       
   291 // -----------------------------------------------------------------------------
       
   292 // COutgoingRequestQueue::UpdateHeadersL
       
   293 // -----------------------------------------------------------------------------
       
   294 //
       
   295 void COutgoingRequestQueue::UpdateHeadersL(
       
   296     TOutgoingRequestQueueItem& aItem,
       
   297     const TInetAddr& aLocalAddr, 
       
   298     const TInetAddr& aPublicAddr )
       
   299     {
       
   300     // Some NAT-aware proxies/registrars detect from the private IP address
       
   301     // that the UA is behind a NAT and maintain a persistent TCP-connection.
       
   302     // If the public address is used with TCP, 
       
   303     // these proxies/registrars will not maintain persistent TCP-connection. 
       
   304     if ( aItem.OrigTransport() == KProtocolInetUdp )
       
   305         {
       
   306         HBufC8* localAddrBuf = 
       
   307             CTransport::ConvertInetAddrToTextL( aLocalAddr );
       
   308     	CleanupStack::PushL( localAddrBuf );
       
   309     	
       
   310     	HBufC8* publicAddrBuf = 
       
   311     	    CTransport::ConvertInetAddrToTextL( aPublicAddr );
       
   312     	CleanupStack::PushL( publicAddrBuf );
       
   313     	
       
   314     	TUint publicPort( aPublicAddr.Port() );
       
   315     	
       
   316     	UpdateContactHeaderL( aItem.Request(), *localAddrBuf, 
       
   317     	                      *publicAddrBuf, publicPort );
       
   318     	                      
       
   319     	UpdateViaHeaderL( aItem.Request(), *publicAddrBuf, publicPort );                    
       
   320     	
       
   321     	CleanupStack::PopAndDestroy( publicAddrBuf );
       
   322     	CleanupStack::PopAndDestroy( localAddrBuf );
       
   323         }
       
   324     }
       
   325 
       
   326 // -----------------------------------------------------------------------------
       
   327 // COutgoingRequestQueue::UpdateContactHeaderL
       
   328 // -----------------------------------------------------------------------------
       
   329 //
       
   330 void COutgoingRequestQueue::UpdateContactHeaderL(
       
   331     CSIPMessage& aMessage,
       
   332     const TDesC8& aLocalAddr, 
       
   333     const TDesC8& aPublicAddr,
       
   334     TUint aPublicPort )  
       
   335     {
       
   336     if ( aMessage.HasHeader( 
       
   337                         SIPStrings::StringF(SipStrConsts::EContactHeader) ) )
       
   338 		{
       
   339         TSglQueIter<CSIPHeaderBase> iter = 
       
   340             aMessage.Headers( 
       
   341                 SIPStrings::StringF(SipStrConsts::EContactHeader) );
       
   342 		CSIPHeaderBase* header = 0;
       
   343 		while ( ( header = iter++ ) != 0 )
       
   344 			{
       
   345 			CSIPContactHeader* contact = 
       
   346 			        static_cast<CSIPContactHeader*>( header );
       
   347 			CSIPAddress* sipAddr = contact->SIPAddress();
       
   348 
       
   349 			if ( sipAddr )
       
   350 			    {
       
   351 			    CURIContainer& uriContainer = sipAddr->URI();
       
   352 			    if ( uriContainer.IsSIPURI() && 
       
   353 			         uriContainer.SIPURI()->HostPort().Host().Compare( 
       
   354 			            aLocalAddr ) == 0 )
       
   355 			        {
       
   356 			        uriContainer.SIPURI()->HostPort().SetHostL( aPublicAddr );
       
   357 			        uriContainer.SIPURI()->HostPort().SetPort( aPublicPort );
       
   358 			        }
       
   359 			    }
       
   360 			}
       
   361 		}
       
   362     }
       
   363     
       
   364 // -----------------------------------------------------------------------------
       
   365 // COutgoingRequestQueue::UpdateViaHeaderL
       
   366 // -----------------------------------------------------------------------------
       
   367 //
       
   368 void COutgoingRequestQueue::UpdateViaHeaderL(
       
   369     CSIPMessage& aMessage,
       
   370     const TDesC8& aPublicAddr,
       
   371     TUint aPublicPort )
       
   372     {
       
   373     CSIPViaHeader* via = CTransport::TopViaHeader( &aMessage );
       
   374     if ( via )
       
   375         {
       
   376         via->SentByHostPort().SetHostL( aPublicAddr );
       
   377     	via->SentByHostPort().SetPort( aPublicPort );
       
   378         }
       
   379     }    
       
   380     
       
   381 // -----------------------------------------------------------------------------
       
   382 // COutgoingRequestQueue::HandleUsagePermissionChange
       
   383 // -----------------------------------------------------------------------------
       
   384 //   
       
   385 void COutgoingRequestQueue::HandleUsagePermissionChange( 
       
   386     TOutgoingRequestQueueItem& aItem, 
       
   387     TBool aPermissionToUse )
       
   388     {     
       
   389     aItem.SetPermissionToUse( aPermissionToUse );
       
   390     
       
   391     if ( !aPermissionToUse && aItem.IsActiveRequest() )
       
   392         {
       
   393         CancelSend( aItem.Status() );
       
   394         }
       
   395     }
       
   396 
       
   397 // -----------------------------------------------------------------------------
       
   398 // COutgoingRequestQueue::HasRequestForSocket
       
   399 // -----------------------------------------------------------------------------
       
   400 //
       
   401 TBool COutgoingRequestQueue::HasRequestForSocket( 
       
   402     RSocket& aSocket, 
       
   403     TBool aFindPendingRequest )
       
   404     {
       
   405     for ( TInt i = 0; i < iRequestQueue.Count(); i++ )
       
   406         {
       
   407         TOutgoingRequestQueueItem& item = iRequestQueue[ i ];
       
   408         if ( item.Match( aSocket ) && 
       
   409              !item.IsFailed() &&
       
   410              ( item.IsActiveRequest() ^ aFindPendingRequest ) )
       
   411             {
       
   412             return ETrue;
       
   413             }
       
   414         }
       
   415     return EFalse;
       
   416     }
       
   417 
       
   418 // -----------------------------------------------------------------------------
       
   419 // COutgoingRequestQueue::CleanupFailedRequests
       
   420 // -----------------------------------------------------------------------------
       
   421 //
       
   422 void COutgoingRequestQueue::CleanupFailedRequests()
       
   423     {
       
   424     TInt lastIndex( iRequestQueue.Count() - 1 );
       
   425     for ( TInt i = lastIndex; i >= 0; i-- )
       
   426         {
       
   427         TOutgoingRequestQueueItem& item = iRequestQueue[ i ];
       
   428         if ( item.IsFailed() )
       
   429             {
       
   430             iContext.RequestFailed( item.Status(), item.Error() );
       
   431             iRequestQueue.Remove( i );
       
   432             iRequestQueue.Compress();
       
   433             }
       
   434         }
       
   435     }
       
   436 
       
   437 // -----------------------------------------------------------------------------
       
   438 // COutgoingRequestQueue::ActivatePendingRequests
       
   439 // -----------------------------------------------------------------------------
       
   440 //    
       
   441 void COutgoingRequestQueue::ActivatePendingRequests()
       
   442     {
       
   443     for ( TInt i = 0; i < iRequestQueue.Count(); i++ )
       
   444         {
       
   445         TOutgoingRequestQueueItem& item = iRequestQueue[ i ];
       
   446         
       
   447         // Activate if there's no other active request for the socket
       
   448         // this pending request uses.
       
   449         if ( !item.IsActiveRequest() && 
       
   450              !HasRequestForSocket( item.Socket(), EFalse ) &&
       
   451              item.PermissionToUse() )
       
   452             {
       
   453             TRAPD( err, IssueRequestL( item ) );
       
   454             item.SetFailed( err );
       
   455             if ( err && !HasRequestForSocket( item.Socket(), ETrue ) )
       
   456                 {
       
   457                 // If no more pending requests, inform that socket is free
       
   458                 iContext.UdpSocketFree( item.Params(), 
       
   459                                         item.Addr(), 
       
   460                                         item.LocalPort(), 
       
   461                                         this,
       
   462                                         item.Socket() );
       
   463                 }            
       
   464             }
       
   465         }
       
   466     CleanupFailedRequests();
       
   467     }
       
   468 
       
   469 // -----------------------------------------------------------------------------
       
   470 // COutgoingRequestQueue::IssueRequestL
       
   471 // -----------------------------------------------------------------------------
       
   472 // 
       
   473 void COutgoingRequestQueue::IssueRequestL( TOutgoingRequestQueueItem& aItem )
       
   474     {
       
   475     __ASSERT_ALWAYS( !HasRequestForSocket( aItem.Socket(), EFalse ), 
       
   476                      User::Leave( KErrInUse ) );      
       
   477                      
       
   478     TPtrC8 domain( KNullDesC8 );
       
   479     CSIPURI* toSIPURI = aItem.Request().To()->SIPAddress().URI().SIPURI();
       
   480     if ( toSIPURI )
       
   481         {
       
   482         domain.Set( toSIPURI->HostPort().Host() );
       
   483         }
       
   484                      
       
   485     // Have to do const cast for transport params to get binding observer
       
   486     TUint32 requestId = iNATTraversal.ResolvePublicAddrL( 
       
   487         iIapId, 
       
   488         iConnection, 
       
   489         iLocalAddr,
       
   490         domain,
       
   491         aItem.Socket(),
       
   492         aItem.Addr(),
       
   493         const_cast<TSIPTransportParams&>( aItem.Params() ).NATBindingObserver(),
       
   494         *this );
       
   495     
       
   496     aItem.SetRequestId( requestId );
       
   497     aItem.SetFailed( KErrNone );
       
   498     }
       
   499     
       
   500 // -----------------------------------------------------------------------------
       
   501 // COutgoingRequestQueue::FindRequestQueueItemIndex
       
   502 // -----------------------------------------------------------------------------
       
   503 //  
       
   504 TInt COutgoingRequestQueue::FindRequestQueueItemIndex( TUint32 aRequestId ) const
       
   505     {
       
   506     for ( TInt i = 0; i < iRequestQueue.Count(); i++ )
       
   507         {
       
   508         if ( iRequestQueue[ i ].Match( aRequestId ) )
       
   509             {
       
   510             return i;
       
   511             }
       
   512         }
       
   513     return KErrNotFound;
       
   514     }
       
   515     
       
   516 // -----------------------------------------------------------------------------
       
   517 // COutgoingRequestQueue::RemoveNATTraversalParameter
       
   518 // -----------------------------------------------------------------------------
       
   519 //
       
   520 void COutgoingRequestQueue::RemoveNATTraversalParameter( CSIPRequest& aRequest )
       
   521     {
       
   522     CSIPToHeader* to = aRequest.To();
       
   523     if ( to )
       
   524         {
       
   525         to->DeleteParam( iStrNATTraversalRequired );
       
   526         }
       
   527     CSIPFromHeader* from = aRequest.From();
       
   528     if ( from )
       
   529         {
       
   530         from->DeleteParam( iStrNATTraversalRequired );
       
   531         }   
       
   532     }
       
   533 
       
   534 // -----------------------------------------------------------------------------
       
   535 // COutgoingRequestQueue::ContactPortL
       
   536 // -----------------------------------------------------------------------------
       
   537 //   
       
   538 TUint COutgoingRequestQueue::ContactPortL( 
       
   539     CSIPRequest& aRequest,
       
   540     const TDesC8& aLocalAddr )
       
   541     {
       
   542     if ( aRequest.HasHeader( 
       
   543             SIPStrings::StringF(SipStrConsts::EContactHeader) ) )
       
   544 		{
       
   545         TSglQueIter<CSIPHeaderBase> iter = 
       
   546             aRequest.Headers( 
       
   547                 SIPStrings::StringF(SipStrConsts::EContactHeader) );
       
   548 		CSIPHeaderBase* header = 0;
       
   549 		while ( ( header = iter++ ) != 0 )
       
   550 			{
       
   551 			CSIPContactHeader* contact = 
       
   552 			        static_cast<CSIPContactHeader*>( header );
       
   553 			CSIPAddress* sipAddr = contact->SIPAddress();
       
   554 			
       
   555 			if ( sipAddr )
       
   556 			    {
       
   557 			    CURIContainer& uriContainer = sipAddr->URI();
       
   558 			    if ( uriContainer.IsSIPURI() && 
       
   559 			         uriContainer.SIPURI()->HostPort().Host().Compare( 
       
   560 			            aLocalAddr ) == 0 &&
       
   561 			         uriContainer.SIPURI()->HostPort().HasPort() )
       
   562 			        {
       
   563 			        return uriContainer.SIPURI()->HostPort().Port();
       
   564 			        }
       
   565 			    }
       
   566 			}
       
   567 		}
       
   568     return 0;
       
   569     }
       
   570 
       
   571 // -----------------------------------------------------------------------------
       
   572 // COutgoingRequestQueue::ConvertToSIPURIRollBack
       
   573 // -----------------------------------------------------------------------------
       
   574 //
       
   575 void COutgoingRequestQueue::ConvertToSIPURIRollBack(TAny* /*aDummy*/)
       
   576     {
       
   577     SIPHeaderLookup::SetConvertToSIPURI(ETrue);
       
   578     }
       
   579 
       
   580 // -----------------------------------------------------------------------------
       
   581 // COutgoingRequestQueue::ConstructL
       
   582 // -----------------------------------------------------------------------------
       
   583 // 
       
   584 void COutgoingRequestQueue::ConstructL()
       
   585     {   
       
   586     _LIT8( KNATTraversalRequired, "nat_traversal_required" );    
       
   587     
       
   588     iStrNATTraversalRequired = 
       
   589         SIPStrings::Pool().OpenFStringL( KNATTraversalRequired ); 
       
   590     }
       
   591     
       
   592 // -----------------------------------------------------------------------------
       
   593 // COutgoingRequestQueue::COutgoingRequestQueue
       
   594 // -----------------------------------------------------------------------------
       
   595 //    
       
   596 COutgoingRequestQueue::COutgoingRequestQueue(
       
   597     MOutgoingRequestQueueContext& aContext,
       
   598     CSIPNATTraversalController& aNATTraversal,
       
   599     RConnection& aConnection,
       
   600     TUint32 aIapId ) :
       
   601     iContext( aContext ),
       
   602     iNATTraversal( aNATTraversal ),
       
   603     iConnection( aConnection ),
       
   604     iIapId( aIapId ),
       
   605     iRequestQueue( KRequestQueueGranularity )
       
   606     {
       
   607     }
       
   608     
       
   609 // End of file