natplugins/natptraversalcontroller/src/cnattraversalcontroller.cpp
changeset 0 1bce908db942
equal deleted inserted replaced
-1:000000000000 0:1bce908db942
       
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "cnattraversalcontroller.h"
       
    20 #include "sipnattraversalcontrollerinitparams.h"
       
    21 #include "sipnatbindingobserver.h"
       
    22 #include "sipnattraversalrequestobserver.h"
       
    23 #include "cnattraversalconfig.h"
       
    24 #include "cnattraversalsession.h"
       
    25 #include "nattraversalsocketuser.h"
       
    26 #include "nattraversallog.h"
       
    27 #include <siperr.h>
       
    28 
       
    29 _LIT8(KZeroIPAddress, "0.0.0.0");
       
    30 
       
    31 // -----------------------------------------------------------------------------
       
    32 // CNATTraversalController::NewL
       
    33 // -----------------------------------------------------------------------------
       
    34 //
       
    35 CNATTraversalController* CNATTraversalController::NewL(TAny* aInitParams)
       
    36     {
       
    37     __ASSERT_ALWAYS (aInitParams, User::Leave(KErrArgument));
       
    38     TSIPNATTraversalControllerInitParams* params =
       
    39         static_cast<TSIPNATTraversalControllerInitParams*>(aInitParams);
       
    40     CNATTraversalController* self =
       
    41         new(ELeave)CNATTraversalController(params->iSocketServ);
       
    42     CleanupStack::PushL(self);
       
    43     self->ConstructL();
       
    44     CleanupStack::Pop(self);
       
    45     return self;
       
    46     }
       
    47 
       
    48 // -----------------------------------------------------------------------------
       
    49 // CNATTraversalController::CNATTraversalController
       
    50 // -----------------------------------------------------------------------------
       
    51 //
       
    52 CNATTraversalController::CNATTraversalController(RSocketServ& aSocketServ)
       
    53  : iSocketServ(aSocketServ),
       
    54    iRequestOrder(TNATTraversalPendingRequest::RequestOrder)
       
    55     {
       
    56     }
       
    57 
       
    58 // -----------------------------------------------------------------------------
       
    59 // CNATTraversalController::ConstructL
       
    60 // -----------------------------------------------------------------------------
       
    61 //
       
    62 void CNATTraversalController::ConstructL()
       
    63     {
       
    64     iDeltaTimer = CDeltaTimer::NewL(CActive::EPriorityStandard);
       
    65     }
       
    66 
       
    67 // -----------------------------------------------------------------------------
       
    68 // CNATTraversalController::~CNATTraversalController
       
    69 // -----------------------------------------------------------------------------
       
    70 //
       
    71 CNATTraversalController::~CNATTraversalController()
       
    72     {
       
    73     iSessions.ResetAndDestroy();
       
    74     for (TInt i=0; i < iPendingRequests.Count(); i++)
       
    75         {
       
    76         if (iDeltaTimer)
       
    77             {
       
    78             iDeltaTimer->Remove(iPendingRequests[i].DeltaTimerEntry());
       
    79             }
       
    80         }
       
    81     iPendingRequests.Close();
       
    82     delete iDeltaTimer;
       
    83     iSocketUserQueue.Close();
       
    84     }
       
    85 
       
    86 // -----------------------------------------------------------------------------
       
    87 // CNATTraversalController::ResolvePublicAddrL
       
    88 // From CSIPNATTraversalController
       
    89 // -----------------------------------------------------------------------------
       
    90 //
       
    91 TUint32 CNATTraversalController::ResolvePublicAddrL(
       
    92     TUint32 aIapId,
       
    93     RConnection& aConnection,
       
    94     const TInetAddr& aLocalAddr,
       
    95     const TDesC8& aDomain,
       
    96     RSocket& aUdpSocket,
       
    97     const TInetAddr& aNextHopAddr,
       
    98     MSIPNATBindingObserver* aBindingObserver,
       
    99     MSIPNATTraversalRequestObserver& aRequestObserver)
       
   100     {
       
   101     __ASSERT_ALWAYS(NULL != aBindingObserver,User::Leave(KErrArgument));
       
   102     TUint32 requestId = NextRequestId();
       
   103     TBool asyncCallInitiated = EFalse;
       
   104 
       
   105     if (!BindingExists(aBindingObserver))
       
   106         {
       
   107         CNATTraversalConfig* config = CNATTraversalConfig::NewLC(aIapId,aDomain);
       
   108 
       
   109         CreateBindingL(requestId,config,aConnection,aLocalAddr,aUdpSocket,
       
   110                        aNextHopAddr,*aBindingObserver,aRequestObserver,
       
   111                        asyncCallInitiated);
       
   112 
       
   113         CleanupStack::Pop(config); // ownership transferred
       
   114         }
       
   115 
       
   116     if (!asyncCallInitiated)
       
   117         {
       
   118         // Start a timer with a minimum value to make the call asynchronous
       
   119         TNATTraversalPendingRequest request(requestId,&aRequestObserver,*this);
       
   120         iPendingRequests.InsertInOrderL(request,iRequestOrder);
       
   121         TInt index = iPendingRequests.FindInOrder(request,iRequestOrder);
       
   122         if (0 <= index && iPendingRequests.Count() > index)
       
   123             {
       
   124             iDeltaTimer->Queue(1,iPendingRequests[index].DeltaTimerEntry());
       
   125             }
       
   126         }
       
   127 
       
   128     return requestId;
       
   129     }
       
   130 
       
   131 // -----------------------------------------------------------------------------
       
   132 // CNATTraversalController::Cancel
       
   133 // From CSIPNATTraversalController
       
   134 // -----------------------------------------------------------------------------
       
   135 //
       
   136 void CNATTraversalController::Cancel(TUint32 aRequestId)
       
   137     {
       
   138     NATTRAVERSAL_LOG("CNATTraversalController::Cancel")
       
   139     TNATTraversalPendingRequest tmp(aRequestId,0,*this);
       
   140     TInt index = iPendingRequests.FindInOrder(tmp,iRequestOrder);
       
   141     if (0 <= index && iPendingRequests.Count() > index)
       
   142         {
       
   143         iDeltaTimer->Remove(iPendingRequests[index].DeltaTimerEntry());
       
   144         iPendingRequests.Remove(index);
       
   145         }
       
   146     else
       
   147         {
       
   148         TBool found = EFalse;
       
   149         for (TInt i=0; i < iSessions.Count() && !found; i++)
       
   150             {
       
   151             found = iSessions[i]->RemoveBinding(aRequestId);
       
   152             }
       
   153         }
       
   154     }
       
   155 
       
   156 // -----------------------------------------------------------------------------
       
   157 // CNATTraversalController::RefreshNATBindingL
       
   158 // From CSIPNATTraversalController
       
   159 // -----------------------------------------------------------------------------
       
   160 //
       
   161 TBool CNATTraversalController::RefreshNATBindingL(
       
   162     RSocket& aSocket,
       
   163     const MSIPNATBindingObserver* aBindingObserver)
       
   164     {
       
   165     NATTRAVERSAL_LOG("CNATTraversalController::RefreshNATBindingL - TCP/UDP")
       
   166     TBool maintainPersistentConnection = EFalse;
       
   167     TBool handled = EFalse;
       
   168     for (TInt i=0; i < iSessions.Count() && !handled; i++)
       
   169         {
       
   170         iSessions[i]->RefreshNATBindingL(
       
   171             aSocket,aBindingObserver,
       
   172             maintainPersistentConnection,handled);
       
   173         }
       
   174     return maintainPersistentConnection;
       
   175     }
       
   176 
       
   177 // -----------------------------------------------------------------------------
       
   178 // CNATTraversalController::RefreshNATBindingL
       
   179 // From CSIPNATTraversalController
       
   180 // -----------------------------------------------------------------------------
       
   181 //
       
   182 TBool CNATTraversalController::RefreshNATBindingL(
       
   183     CSecureSocket& aSecureSocket,
       
   184     const MSIPNATBindingObserver* aBindingObserver)
       
   185     {
       
   186     NATTRAVERSAL_LOG("CNATTraversalController::RefreshNATBindingL - TLS")
       
   187     TBool maintainPersistentConnection = EFalse;
       
   188     TBool handled = EFalse;
       
   189     for (TInt i=0; i < iSessions.Count() && !handled; i++)
       
   190         {
       
   191         iSessions[i]->RefreshNATBindingL(
       
   192             aSecureSocket,aBindingObserver,
       
   193             maintainPersistentConnection,handled);
       
   194         }
       
   195     return maintainPersistentConnection;
       
   196     }
       
   197 
       
   198 // -----------------------------------------------------------------------------
       
   199 // CNATTraversalController::UpdateNextHop
       
   200 // -----------------------------------------------------------------------------
       
   201 //
       
   202 void CNATTraversalController::UpdateNextHop(
       
   203     const TInetAddr& aNextHopAddr,
       
   204     const MSIPNATBindingObserver* aBindingObserver)
       
   205     {
       
   206     NATTRAVERSAL_ADDRLOG("CNATTraversalController::UpdateNextHop ->",
       
   207         aNextHopAddr)
       
   208     for (TInt i=0; i < iSessions.Count(); i++)
       
   209         {
       
   210         CNATTraversalSession* session = iSessions[i];
       
   211         if (session->HasBinding(aBindingObserver))
       
   212             {
       
   213             session->UpdateNextHop(aNextHopAddr);
       
   214             return;
       
   215             }
       
   216         }
       
   217     }
       
   218 
       
   219 // -----------------------------------------------------------------------------
       
   220 // CNATTraversalController::SocketIdle
       
   221 // From CSIPNATTraversalController
       
   222 // -----------------------------------------------------------------------------
       
   223 //
       
   224 void CNATTraversalController::SocketIdle(
       
   225     TBool aIdle,
       
   226     RSocket& aSocket)
       
   227     {
       
   228     NATTRAVERSAL_INTLOG("CNATTraversalController::SocketIdle - TCP/UDP", aIdle)
       
   229     for (TInt i=0; i < iSessions.Count(); i++)
       
   230         {
       
   231         iSessions[i]->SocketIdle(aIdle,aSocket);
       
   232         }
       
   233     if (!aIdle)
       
   234         {
       
   235         TBool firstRemoved = EFalse;
       
   236         for (TInt i=iSocketUserQueue.Count()-1; i >= 0; i--)
       
   237             {
       
   238             const RSocket& socket = iSocketUserQueue[i]->Socket();
       
   239             if (socket.SubSessionHandle() == aSocket.SubSessionHandle())
       
   240                 {
       
   241                 iSocketUserQueue[i]->CancelSending();
       
   242                 iSocketUserQueue.Remove(i);
       
   243                 firstRemoved = (i == 0);
       
   244                 }
       
   245             }
       
   246         if (firstRemoved)
       
   247             {
       
   248             HandleNextFromSocketUserQueue();
       
   249             }
       
   250         }
       
   251     }
       
   252 
       
   253 // -----------------------------------------------------------------------------
       
   254 // CNATTraversalController::SocketIdle
       
   255 // From CSIPNATTraversalController
       
   256 // -----------------------------------------------------------------------------
       
   257 //
       
   258 void CNATTraversalController::SocketIdle(
       
   259     TBool aIdle,
       
   260     CSecureSocket& aSecureSocket)
       
   261     {
       
   262     NATTRAVERSAL_INTLOG("CNATTraversalController::SocketIdle - TLS", aIdle)
       
   263     for (TInt i=0; i < iSessions.Count(); i++)
       
   264         {
       
   265         iSessions[i]->SocketIdle(aIdle,aSecureSocket);
       
   266         }
       
   267     }
       
   268 
       
   269 // -----------------------------------------------------------------------------
       
   270 // CNATTraversalController::DataReceived
       
   271 // From CSIPNATTraversalController
       
   272 // -----------------------------------------------------------------------------
       
   273 //
       
   274 void CNATTraversalController::DataReceivedL(
       
   275     const TDesC8& aData,
       
   276     const RSocket& aSocket,
       
   277     TBool& aHandled)
       
   278     {
       
   279     NATTRAVERSAL_LOG("CNATTraversalController::DataReceivedL");
       
   280     aHandled = EFalse;
       
   281     for (TInt i=0; i < iSessions.Count() && !aHandled; i++)
       
   282         {
       
   283         iSessions[i]->DataReceivedL(aData,aSocket,aHandled);
       
   284         }
       
   285     }
       
   286 
       
   287 // -----------------------------------------------------------------------------
       
   288 // CNATTraversalController::FreeResources
       
   289 // From CSIPNATTraversalController
       
   290 // -----------------------------------------------------------------------------
       
   291 //
       
   292 void CNATTraversalController::FreeResources(TUint32 aIapId)
       
   293     {
       
   294     NATTRAVERSAL_LOG("CNATTraversalController::FreeResources for IAP")
       
   295     for (TInt i = iSessions.Count()-1; i >= 0; i--)
       
   296         {
       
   297         CNATTraversalSession* session = iSessions[i];
       
   298         if (session->IapId() == aIapId)
       
   299             {
       
   300             iSessions.Remove(i);
       
   301             delete session;
       
   302             }
       
   303         }
       
   304     }
       
   305 
       
   306 // -----------------------------------------------------------------------------
       
   307 // CNATTraversalController::FreeResources
       
   308 // From CSIPNATTraversalController
       
   309 // -----------------------------------------------------------------------------
       
   310 //
       
   311 void CNATTraversalController::FreeResources(
       
   312     MSIPNATBindingObserver& aBindingObserver)
       
   313     {
       
   314     NATTRAVERSAL_LOG("CNATTraversalController::FreeResources for observer")
       
   315     for (TInt i=iSessions.Count()-1; i>=0; i--)
       
   316         {
       
   317         CNATTraversalSession* session = iSessions[i];
       
   318         session->RemoveBinding(aBindingObserver);
       
   319         if (!session->HasBindings())
       
   320             {
       
   321             iSessions.Remove(i);
       
   322             delete session;
       
   323             }
       
   324         }
       
   325     }
       
   326 
       
   327 // -----------------------------------------------------------------------------
       
   328 // CNATTraversalController::RequestCompleted
       
   329 // From MNATTraversalPendingRequestContainer
       
   330 // -----------------------------------------------------------------------------
       
   331 //
       
   332 void CNATTraversalController::RequestCompleted(
       
   333     TUint32 aRequestId)
       
   334     {
       
   335     NATTRAVERSAL_LOG("CNATTraversalController::RequestCompleted")
       
   336     TNATTraversalPendingRequest tmp(aRequestId,0,*this);
       
   337     TInt index = iPendingRequests.FindInOrder(tmp,iRequestOrder);
       
   338     if (0 <= index && iPendingRequests.Count() > index)
       
   339         {
       
   340         TNATTraversalPendingRequest request = iPendingRequests[index]; // copy
       
   341         iDeltaTimer->Remove(iPendingRequests[index].DeltaTimerEntry());
       
   342         iPendingRequests.Remove(index); // remove from array
       
   343         request.CompleteRequest(); // use copy for informing the observer
       
   344         }
       
   345     }
       
   346 
       
   347 // -----------------------------------------------------------------------------
       
   348 // CNATTraversalController::STUNClientInitCompleted
       
   349 // From MSTUNClientObserver
       
   350 // -----------------------------------------------------------------------------
       
   351 //
       
   352 void CNATTraversalController::STUNClientInitCompleted(
       
   353     const CSTUNClient& aClient,
       
   354     TInt aCompletionCode)
       
   355     {
       
   356     TBool found = EFalse;
       
   357     for (TInt i=0; i<iSessions.Count() && !found; i++)
       
   358         {
       
   359         CNATTraversalSession* session = iSessions[i];
       
   360         if (session->HasSTUNClient(aClient))
       
   361             {
       
   362             found = ETrue;
       
   363             if (aCompletionCode != KErrNone)
       
   364                 {
       
   365                 if (KErrNATFWDnsFailure == aCompletionCode)
       
   366                     {
       
   367                     aCompletionCode = KErrSIPResolvingFailure;
       
   368                     }
       
   369                 session->InitFailed(aCompletionCode);
       
   370                 }
       
   371             else
       
   372                 {
       
   373                 TRAPD(err,session->InitCompletedL());
       
   374                 if (err)
       
   375                     {
       
   376                     session->InitFailed(err);
       
   377                     }
       
   378                 }
       
   379             }
       
   380         }
       
   381     }
       
   382 
       
   383 // -----------------------------------------------------------------------------
       
   384 // CNATTraversalController::STUNBindingEventOccurredL
       
   385 // From MSTUNClientObserver
       
   386 // -----------------------------------------------------------------------------
       
   387 //
       
   388 void CNATTraversalController::STUNBindingEventOccurredL(
       
   389     TSTUNBindingEvent aEvent,
       
   390     const CBinding& aBinding)
       
   391     {
       
   392     if (aEvent == MSTUNClientObserver::EPublicAddressResolved)
       
   393         {
       
   394         TBool found = EFalse;
       
   395         for (TInt i=0; i<iSessions.Count() && !found; i++)
       
   396             {
       
   397             CNATTraversalSession* session = iSessions[i];
       
   398             found = session->AddressResolvedL(aBinding);
       
   399             }
       
   400         }
       
   401     }
       
   402 
       
   403 // -----------------------------------------------------------------------------
       
   404 // CNATTraversalController::STUNBindingErrorOccurred
       
   405 // From MSTUNClientObserver
       
   406 // -----------------------------------------------------------------------------
       
   407 //
       
   408 void CNATTraversalController::STUNBindingErrorOccurred(
       
   409     const CBinding& aBinding,
       
   410     TInt aError)
       
   411     {
       
   412     TBool found = EFalse;
       
   413     for (TInt i=0; i<iSessions.Count() && !found; i++)
       
   414         {
       
   415         CNATTraversalSession* session = iSessions[i];
       
   416         found = session->BindingFailed(aBinding,aError);
       
   417         }
       
   418     }
       
   419 
       
   420 // -----------------------------------------------------------------------------
       
   421 // CNATTraversalController::AddToSendingQueueL
       
   422 // From MNATTraversalSocketManager
       
   423 // -----------------------------------------------------------------------------
       
   424 //
       
   425 TBool CNATTraversalController::AddToSendingQueueL(
       
   426     MNATTraversalSocketUser& aUser)
       
   427     {
       
   428     TBool requestPendingForSocket = EFalse;
       
   429     for (TInt i=0; i < iSocketUserQueue.Count(); i++)
       
   430         {
       
   431         const RSocket& socket = iSocketUserQueue[i]->Socket();
       
   432         if (socket.SubSessionHandle() == aUser.Socket().SubSessionHandle())
       
   433             {
       
   434             requestPendingForSocket = ETrue;
       
   435             }
       
   436         }
       
   437     iSocketUserQueue.AppendL(&aUser);
       
   438     return requestPendingForSocket;
       
   439     }
       
   440 
       
   441 // -----------------------------------------------------------------------------
       
   442 // CNATTraversalController::SendingCompleted
       
   443 // From MNATTraversalSocketManager
       
   444 // -----------------------------------------------------------------------------
       
   445 //
       
   446 void CNATTraversalController::SendingCompleted(MNATTraversalSocketUser& aUser)
       
   447     {
       
   448     TInt index = iSocketUserQueue.Find(&aUser);
       
   449     if (index >= 0)
       
   450         {
       
   451         iSocketUserQueue.Remove(index);
       
   452         if (index == 0)
       
   453             {
       
   454             HandleNextFromSocketUserQueue();
       
   455             }
       
   456         }
       
   457     }
       
   458 
       
   459 // -----------------------------------------------------------------------------
       
   460 // CNATTraversalController::NextRequestId
       
   461 // -----------------------------------------------------------------------------
       
   462 //
       
   463 TUint32 CNATTraversalController::NextRequestId()
       
   464     {
       
   465     if (iRequestIdCounter == KMaxTUint32)
       
   466         {
       
   467         iRequestIdCounter = 1;
       
   468         }
       
   469     else
       
   470         {
       
   471         iRequestIdCounter++;
       
   472         }
       
   473     return iRequestIdCounter;
       
   474     }
       
   475 
       
   476 // -----------------------------------------------------------------------------
       
   477 // CNATTraversalController::CreateBindingL
       
   478 // -----------------------------------------------------------------------------
       
   479 //
       
   480 void CNATTraversalController::CreateBindingL(
       
   481     TUint32 aRequestId,
       
   482     CNATTraversalConfig* aConfig,
       
   483     RConnection& aConnection,
       
   484     const TInetAddr& aLocalAddr,
       
   485     RSocket& aUdpSocket,
       
   486     const TInetAddr& aNextHopAddr,
       
   487     MSIPNATBindingObserver& aBindingObserver,
       
   488     MSIPNATTraversalRequestObserver& aRequestObserver,
       
   489     TBool& aAsyncInitiated)
       
   490     {
       
   491     __ASSERT_ALWAYS(aConfig, User::Leave(KErrArgument));
       
   492 
       
   493     __ASSERT_ALWAYS(!BindingExists(&aBindingObserver),
       
   494                     User::Leave(KErrAlreadyExists));
       
   495 
       
   496     TBool useSTUN = (aConfig->STUNServer().Compare(KZeroIPAddress) != 0);
       
   497     if (!useSTUN)
       
   498         {
       
   499         aAsyncInitiated = EFalse;
       
   500         if ( aConfig->CRLFRefreshEnabledToProxyValue() !=
       
   501         	 CNATTraversalConfig::EEnabled )
       
   502             {
       
   503             // No need to create binding nor a dummy CRLF refresh
       
   504             delete aConfig;
       
   505             return;
       
   506             }
       
   507         }
       
   508 
       
   509     TInt index = FindSessionIndex(aConfig->IapId(),aConfig->Domain());
       
   510     if (index >= 0)
       
   511         {
       
   512         // Session exists
       
   513         CNATTraversalSession* session = iSessions[index];
       
   514         session->CreateNATBindingL(aRequestId,aUdpSocket,
       
   515                                    aBindingObserver,aRequestObserver,
       
   516                                    aAsyncInitiated);
       
   517         delete aConfig; // ownership transferred after leaving functions
       
   518         }
       
   519     else
       
   520         {
       
   521         // Create new session and add a binding
       
   522         CNATTraversalSession* session =
       
   523             CNATTraversalSession::NewLC(*iDeltaTimer,iSocketServ,aConnection,
       
   524                                         aLocalAddr,aNextHopAddr,aConfig,
       
   525                                         *this,*this);
       
   526         TCleanupItem cleanupItem(DetachConfigFromSession,session);
       
   527         CleanupStack::PushL(cleanupItem);
       
   528         session->CreateNATBindingL(aRequestId,aUdpSocket,
       
   529                                    aBindingObserver,aRequestObserver,
       
   530                                    aAsyncInitiated);
       
   531         iSessions.AppendL(session);
       
   532         CleanupStack::Pop(); // cleanupItem
       
   533         CleanupStack::Pop(session);
       
   534         }
       
   535     }
       
   536 
       
   537 // -----------------------------------------------------------------------------
       
   538 // CNATTraversalController::FindSessionIndex
       
   539 // -----------------------------------------------------------------------------
       
   540 //
       
   541 TInt CNATTraversalController::FindSessionIndex(
       
   542     TUint32 aIapId,
       
   543     const TDesC8& aDomain) const
       
   544     {
       
   545     for (TInt i=0; i < iSessions.Count(); i++)
       
   546         {
       
   547         CNATTraversalSession* session = iSessions[i];
       
   548         if (session->IapId() == aIapId &&
       
   549             session->Domain().CompareF(aDomain) == 0)
       
   550             {
       
   551             return i;
       
   552             }
       
   553         }
       
   554     return KErrNotFound;
       
   555     }
       
   556 
       
   557 // -----------------------------------------------------------------------------
       
   558 // CNATTraversalController::BindingExists
       
   559 // -----------------------------------------------------------------------------
       
   560 //
       
   561 TBool CNATTraversalController::BindingExists(
       
   562     const MSIPNATBindingObserver* aObserver) const
       
   563     {
       
   564     for (TInt i=0; i < iSessions.Count(); i++)
       
   565         {
       
   566         if (iSessions[i]->HasBinding(aObserver))
       
   567             {
       
   568             return ETrue;
       
   569             }
       
   570         }
       
   571     return EFalse;
       
   572     }
       
   573 
       
   574 // -----------------------------------------------------------------------------
       
   575 // CNATTraversalController::DetachConfigFromSession
       
   576 // -----------------------------------------------------------------------------
       
   577 //
       
   578 void CNATTraversalController::DetachConfigFromSession(TAny* aSession)
       
   579     {
       
   580     CNATTraversalSession* session =
       
   581         reinterpret_cast<CNATTraversalSession*>(aSession);
       
   582     if (session)
       
   583         {
       
   584         session->DetachConfig();
       
   585         }
       
   586     }
       
   587 
       
   588 // -----------------------------------------------------------------------------
       
   589 // CNATTraversalController::HandleNextFromSocketUserQueue
       
   590 // -----------------------------------------------------------------------------
       
   591 //
       
   592 void CNATTraversalController::HandleNextFromSocketUserQueue()
       
   593     {
       
   594     if (iSocketUserQueue.Count() > 0 && !iSocketUserQueue[0]->IsSending())
       
   595         {
       
   596         iSocketUserQueue[0]->SendingAllowed();
       
   597         }
       
   598     }