natfw/natfwstunturnclient/src/cstunrelaybindingimplementation.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 
       
    20 
       
    21 #include "stunassert.h"
       
    22 #include "natfwunsaflog.h"
       
    23 #include "natfwunsafmessagefactory.h"
       
    24 #include "natfwunsafbindingrequest.h"
       
    25 #include "natfwunsafallocaterequest.h"
       
    26 #include "natfwunsafconnectrequest.h"
       
    27 #include "natfwunsafsetactivedestinationrequest.h"
       
    28 #include "natfwunsafsendindication.h"
       
    29 #include "cstunrelaybindingimplementation.h"
       
    30 #include "natfwstunbinding.h"
       
    31 #include "cstunbindinginit.h"
       
    32 #include "cstunbindinggetsharedsecret.h"
       
    33 #include "cstunbindinggetaddress.h"
       
    34 #include "cstunbindingactive.h"
       
    35 #include "cstunbindingwaittoretry.h"
       
    36 #include "mstunbindingobserver.h"
       
    37 #include "cstuntransaction.h"
       
    38 #include "stunutils.h"
       
    39 #include "natfwstunclientdefs.h"
       
    40 #include "cstunindicationtransmitter.h"
       
    41 #include "natfwunsaftcprelaypacketfactory.h"
       
    42 
       
    43 // Attributes
       
    44 #include "natfwunsafusernameattribute.h"
       
    45 #include "natfwunsafxoronlyattribute.h"
       
    46 #include "natfwunsafunknownattributesattribute.h"
       
    47 #include "natfwunsafmagiccookieattribute.h"
       
    48 #include "natfwunsafdataattribute.h"
       
    49 #include "natfwunsafremoteaddressattribute.h"
       
    50 #include "natfwunsafusecandidateattribute.h"
       
    51 #include "natfwunsafpriorityattribute.h"
       
    52 #include "natfwunsaficecontrollingattribute.h"
       
    53 #include "natfwunsaficecontrolledattribute.h"
       
    54 #include "natfwunsafalternateserverattribute.h"
       
    55 #include "natfwunsafrealmattribute.h"
       
    56 #include "natfwunsafnonceattribute.h"
       
    57 
       
    58 
       
    59 
       
    60 // ======== MEMBER FUNCTIONS ========
       
    61 
       
    62 // ---------------------------------------------------------------------------
       
    63 // CSTUNRelayBindingImplementation::NewL
       
    64 // ---------------------------------------------------------------------------
       
    65 //
       
    66 CSTUNRelayBindingImplementation*
       
    67     CSTUNRelayBindingImplementation::NewL( CBinding& aBinding,  
       
    68                                            MSTUNBindingObserver& aClient,
       
    69                                            RSocket& aSocket )
       
    70     {
       
    71 
       
    72     CSTUNRelayBindingImplementation* self =
       
    73     new ( ELeave ) CSTUNRelayBindingImplementation( aBinding, aClient, aSocket );
       
    74     CleanupStack::PushL( self );
       
    75     self->ConstructL();
       
    76     CleanupStack::Pop( self );
       
    77     return self;
       
    78     }
       
    79 
       
    80 // ---------------------------------------------------------------------------
       
    81 // CSTUNRelayBindingImplementation::NewL - overloaded
       
    82 // ---------------------------------------------------------------------------
       
    83 //
       
    84 CSTUNRelayBindingImplementation*
       
    85     CSTUNRelayBindingImplementation::NewL( CBinding& aBinding,  
       
    86                                            MSTUNBindingObserver& aClient,
       
    87                                            TUint aStreamId,
       
    88                                            TUint aConnectionId,
       
    89                                            MNcmConnectionMultiplexer* aMux )
       
    90     {
       
    91 
       
    92     CSTUNRelayBindingImplementation* self =
       
    93     new ( ELeave ) CSTUNRelayBindingImplementation( aBinding, aClient, aStreamId, 
       
    94                                                aConnectionId, aMux );
       
    95     CleanupStack::PushL( self );
       
    96     self->ConstructL( );
       
    97     CleanupStack::Pop( self );
       
    98     return self;
       
    99     }
       
   100 
       
   101 // ---------------------------------------------------------------------------
       
   102 // CSTUNRelayBindingImplementation::CSTUNRelayBindingImplementation
       
   103 // ---------------------------------------------------------------------------
       
   104 //
       
   105 CSTUNRelayBindingImplementation::CSTUNRelayBindingImplementation(
       
   106     CBinding& aBinding,
       
   107     MSTUNBindingObserver& aClient,
       
   108     RSocket& aSocket ) :
       
   109     CBindingImplementation( aClient, aBinding, aSocket )
       
   110     {
       
   111     }
       
   112 
       
   113 // ---------------------------------------------------------------------------
       
   114 // CSTUNRelayBindingImplementation::CSTUNRelayBindingImplementation
       
   115 // ---------------------------------------------------------------------------
       
   116 //
       
   117 CSTUNRelayBindingImplementation::CSTUNRelayBindingImplementation( 
       
   118     CBinding& aBinding,
       
   119     MSTUNBindingObserver& aClient, 
       
   120     TUint aStreamId,
       
   121     TUint aConnectionId,
       
   122     MNcmConnectionMultiplexer* aMux ) :
       
   123     CBindingImplementation( aClient, aBinding, aStreamId, aConnectionId, aMux )
       
   124     {
       
   125     }
       
   126     
       
   127 // ---------------------------------------------------------------------------
       
   128 // CSTUNRelayBindingImplementation::ConstructL
       
   129 // ---------------------------------------------------------------------------
       
   130 //
       
   131 void CSTUNRelayBindingImplementation::ConstructL()
       
   132     {
       
   133     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::ConstructL" )
       
   134     ClientL().AttachBindingL( iBinding );
       
   135 
       
   136     iGetAddress = new ( ELeave ) CSTUNBindingGetAddress();
       
   137     iGetSharedSecret =
       
   138     new ( ELeave ) CSTUNBindingGetSharedSecret( *iGetAddress );
       
   139     iInit = new ( ELeave ) CSTUNBindingInit( *iGetSharedSecret );
       
   140     iActive = new ( ELeave ) CSTUNBindingActive( *iGetSharedSecret );
       
   141     iWaitToRetry = new ( ELeave ) CSTUNBindingWaitToRetry( *iGetSharedSecret );
       
   142     iGetAddress->SetNeighbourStates( *iGetSharedSecret,
       
   143                                      *iWaitToRetry,
       
   144                                      *iActive );
       
   145     
       
   146     iIndicationTx = CStunIndicationTransmitter::NewL( *iMux, 
       
   147                                                       iStreamId, 
       
   148                                                       iConnectionId );
       
   149     ChangeState( *iInit );
       
   150     }
       
   151 
       
   152 // ---------------------------------------------------------------------------
       
   153 // CSTUNRelayBindingImplementation::~CSTUNRelayBindingImplementation
       
   154 // ---------------------------------------------------------------------------
       
   155 //
       
   156 CSTUNRelayBindingImplementation::~CSTUNRelayBindingImplementation()
       
   157     {
       
   158     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::~CSTUNRelayBindingImplementation" )
       
   159     if ( iClient )
       
   160         {
       
   161         iClient->DetachBinding( iBinding );
       
   162         }
       
   163 
       
   164     this->FreeRequestData();
       
   165 
       
   166     delete iInit;
       
   167     delete iGetSharedSecret;
       
   168     delete iGetAddress;
       
   169     delete iWaitToRetry;
       
   170     delete iActive;
       
   171     delete iIndicationTx;
       
   172     
       
   173     iSocket = NULL;
       
   174     iMux = NULL;
       
   175     
       
   176     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::~CSTUNRelayBindingImplementation exit" )
       
   177     }
       
   178 
       
   179 // -----------------------------------------------------------------------------
       
   180 // CSTUNRelayBindingImplementation::TimerExpiredL
       
   181 // -----------------------------------------------------------------------------
       
   182 //
       
   183 void CSTUNRelayBindingImplementation::TimerExpiredL()
       
   184     {
       
   185     iState->TimerExpiredL( *this );
       
   186     }
       
   187 
       
   188 // -----------------------------------------------------------------------------
       
   189 // CSTUNRelayBindingImplementation::LeaveFromTimerExpired
       
   190 // -----------------------------------------------------------------------------
       
   191 //
       
   192 void CSTUNRelayBindingImplementation::LeaveFromTimerExpired( TInt aError )
       
   193     {
       
   194     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::LeaveFromTimerExpired" )
       
   195     __STUN_ASSERT_RETURN( aError != KErrNone, KErrArgument );
       
   196 
       
   197     Terminate( aError );
       
   198     }
       
   199 
       
   200 // ---------------------------------------------------------------------------
       
   201 // CSTUNRelayBindingImplementation::PublicAddressObtainedL
       
   202 // ---------------------------------------------------------------------------
       
   203 //
       
   204 void CSTUNRelayBindingImplementation::PublicAddressObtainedL( 
       
   205     const TInetAddr& aAddress )
       
   206     {
       
   207     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::PublicAddressObtainedL 1" )
       
   208     iState->PublicAddressReceivedL( *this, aAddress );
       
   209     }
       
   210 
       
   211 // ---------------------------------------------------------------------------
       
   212 // CSTUNRelayBindingImplementation::PublicAddressObtainedL
       
   213 // ---------------------------------------------------------------------------
       
   214 //
       
   215 void CSTUNRelayBindingImplementation::PublicAddressObtainedL( 
       
   216     const TInetAddr& aReflexiveAddr, const TInetAddr& aRelayAddr )
       
   217     {
       
   218     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::PublicAddressObtainedL 2" )
       
   219     iState->PublicAddressReceivedL( *this, aReflexiveAddr, aRelayAddr );
       
   220     }
       
   221 
       
   222 // ---------------------------------------------------------------------------
       
   223 // CSTUNRelayBindingImplementation::TransactionError
       
   224 // ---------------------------------------------------------------------------
       
   225 //
       
   226 void CSTUNRelayBindingImplementation::TransactionError( TInt aError,
       
   227     CNATFWUNSAFUnknownAttributesAttribute* aUnknownAttr )
       
   228     {
       
   229     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::TransactionError" )
       
   230     delete iUnknownAttr;
       
   231     iUnknownAttr = aUnknownAttr;
       
   232 
       
   233     __STUN_ASSERT_RETURN( aError != KErrNone, KErrArgument );
       
   234     iState->TransactionError( *this, aError );
       
   235     }
       
   236 
       
   237 // ---------------------------------------------------------------------------
       
   238 // CSTUNRelayBindingImplementation::TransactionEventOccurredL
       
   239 // ---------------------------------------------------------------------------
       
   240 //
       
   241 void CSTUNRelayBindingImplementation::TransactionEventOccurredL( 
       
   242     TSTUNCallbackInfo::TFunction aEvent )
       
   243     {
       
   244     __STUNTURNCLIENT_INT1( 
       
   245         "CSTUNRelayBindingImplementation::TransactionEventOccurredL event:",
       
   246              aEvent )
       
   247     if ( ESetActiveDestinationRequest == iRequestType )
       
   248         {
       
   249         *iTimerValue = iTransaction->TimerValue();
       
   250         }
       
   251     
       
   252     FreeRequestData();
       
   253     ChangeState( *iActive );
       
   254     ClientL().BindingEventOccurred( iBinding, aEvent );
       
   255     }
       
   256 
       
   257 // ---------------------------------------------------------------------------
       
   258 // CSTUNRelayBindingImplementation::HandleTransactionError
       
   259 // ---------------------------------------------------------------------------
       
   260 //  
       
   261 TBool CSTUNRelayBindingImplementation::HandleTransactionError( TInt aError )
       
   262     {
       
   263     __STUNTURNCLIENT_INT1( "HandleTransactionError, reason", aError )
       
   264        
       
   265     const TInt KMaxErrorResponseCount = 3;
       
   266 
       
   267     __STUN_ASSERT_RETURN_VALUE( iRequest && aError != KErrNone,
       
   268     EFalse );
       
   269     
       
   270     delete iTransaction;
       
   271     iTransaction = NULL;
       
   272     iTransactionError = aError;
       
   273 
       
   274     if ( ( aError > 0 ) && ( ++iErrorResponseCount >= KMaxErrorResponseCount ) )
       
   275         {
       
   276         iErrorResponseCount = 0;
       
   277         return EFalse;
       
   278         }
       
   279         
       
   280     CNATFWUNSAFAlternateServerAttribute* alternateServer = NULL;
       
   281     HBufC8* realmValue = NULL;
       
   282     
       
   283     switch ( aError )
       
   284         {
       
   285         case KErrTimedOut:
       
   286             __STUNTURNCLIENT( 
       
   287                 "CSTUNRelayBindingImplementation - KErrTimedOut" )
       
   288             //Clear iAddXorOnly as another address is tried
       
   289             iAddXorOnly = EFalse;
       
   290             return iClient && iClient->ObtainServerAddress( iServerAddress );
       
   291         
       
   292         case E300TryAlternate:
       
   293             // The client SHOULD attempt a new transaction to the server
       
   294             // indicated in the ALTERNATE-SERVER attribute.
       
   295             alternateServer = static_cast<CNATFWUNSAFAlternateServerAttribute*>
       
   296             ( iRequest->Attribute( CNATFWUNSAFAttribute::EAlternateServer ) );
       
   297             if ( alternateServer )
       
   298                 {
       
   299                 iServerAddress = alternateServer->Address();
       
   300                 return ETrue;
       
   301                 }
       
   302             return EFalse;
       
   303         
       
   304         case E4XX:
       
   305             return EFalse;
       
   306                         
       
   307         case E401Unauthorized:        
       
   308             if ( iSharedSecret )
       
   309                 {                                              
       
   310                 CNATFWUNSAFRealmAttribute* realm = 
       
   311                     static_cast<CNATFWUNSAFRealmAttribute*>
       
   312                     ( iRequest->Attribute( CNATFWUNSAFAttribute::ERealm ) );
       
   313                 if ( realm || !iRealmFromResponse )
       
   314                     {
       
   315                     // indicates that this was retry and it did not work.
       
   316                     // notify client -> unrecoverable error
       
   317                     return EFalse;                   
       
   318                     }
       
   319                 }
       
   320             return ETrue;    
       
   321 
       
   322         case E420UnknownAttributes:
       
   323             //Remove the unknown attributes and retry
       
   324             return iUnknownAttr != NULL;
       
   325                             
       
   326         case E430StaleCredentials:
       
   327             // Client used a short term credential that has expired so
       
   328             // generate a new Shared Secret request            
       
   329             return iSharedSecret != NULL;
       
   330 
       
   331         case E431IntegrityCheckFailure:
       
   332             {
       
   333             TBool retry = EFalse;
       
   334             TRAPD( err, retry =
       
   335                 ClientL().SharedSecretRejectedL( iBinding,
       
   336                                                  Username(),
       
   337                                                  *iSharedSecret ) );
       
   338             return err == KErrNone && retry;
       
   339             }
       
   340                     
       
   341         case E432MissingUsername:
       
   342             //If missing USERNAME or MESSAGE-INTEGRITY, add them and retry
       
   343             return !iRequest->Attribute( CNATFWUNSAFAttribute::EUsername ) ||
       
   344                !iSharedSecret;
       
   345                
       
   346         case E433UseTLS:
       
   347             // If request was a Shared Secret request and wasn't sent over
       
   348             // TLS, the client SHOULD retry the request with TLS.
       
   349             return iSharedSecret != NULL;
       
   350 
       
   351         case E434MissingRealm:
       
   352             if ( !iRequest->Attribute( CNATFWUNSAFAttribute::ERealm ) &&
       
   353                  iSharedSecret )
       
   354                 {
       
   355                 // use a long term credential and retry the request using the username
       
   356                 // and password associated with the REALM
       
   357                 return ETrue;
       
   358                 }
       
   359                 
       
   360             TRAPD( err, realmValue = ( static_cast<CNATFWUNSAFRealmAttribute*>
       
   361                 ( iRequest->Attribute( CNATFWUNSAFAttribute::ERealm ) ) )->
       
   362                 Value().AllocL() );
       
   363             if ( err || !realmValue )
       
   364                 {
       
   365                 delete realmValue;
       
   366                 return EFalse;
       
   367                 }
       
   368                 
       
   369             if (  KErrNone != realmValue->Compare( *iRealmFromResponse ) )
       
   370                 {
       
   371                 // the client SHOULD retry using the username and 
       
   372                 // password associated with the REALM in the response
       
   373                 iUseRealmFromResponse = ETrue;
       
   374                 delete realmValue;
       
   375                 return ETrue;
       
   376                 }
       
   377             delete realmValue;           
       
   378             return EFalse;                                    
       
   379               
       
   380  
       
   381         case E435MissingNonce:
       
   382             if ( iRequest->Attribute( CNATFWUNSAFAttribute::ENonce ) )
       
   383                 {
       
   384                 return EFalse; 
       
   385                 }
       
   386             // retry using a nonce from error response                
       
   387             return ETrue;
       
   388                       
       
   389         case E436UnknownUsername:
       
   390             if ( iSharedSecret )
       
   391                 {
       
   392                 return ETrue;                
       
   393                 }
       
   394             // If the username was collected from the user, alert the user.
       
   395             return EFalse;
       
   396 
       
   397         case E437NoBindind:
       
   398             // There is none yet in place
       
   399             return EFalse;
       
   400 
       
   401         case E438StaleNonce:                                  
       
   402             if ( iRequest->Attribute( CNATFWUNSAFAttribute::ENonce ) )
       
   403                 {
       
   404                 // retry using a nonce from error response
       
   405                 return ETrue;
       
   406                 }
       
   407             return EFalse;
       
   408             
       
   409         case E439Transitioning:
       
   410             // The client should reset the active destination, wait for 
       
   411             // 5 seconds and set the active destination to the new value.
       
   412             return EFalse;
       
   413             
       
   414         case E442UnsupportedTransportProtocol:
       
   415 
       
   416             return EFalse;
       
   417                     
       
   418         case E443InvalidIPAddress:
       
   419             
       
   420             return EFalse;           
       
   421             
       
   422         case E444InvalidPort:
       
   423         
       
   424             return EFalse;
       
   425 
       
   426         case E445OperationForTCPOnly:
       
   427 
       
   428             return EFalse;
       
   429 
       
   430         case E446ConnectionAlreadyExists:
       
   431          
       
   432             return EFalse;
       
   433             
       
   434         case E486AllocationQuotaReached:
       
   435             // The user or client is not authorized to request additional
       
   436             // allocations.          
       
   437             return EFalse;
       
   438 
       
   439         case E500ServerError:               
       
   440             return ETrue;  
       
   441                                       
       
   442         case E507InsufficientCapacity:
       
   443             // The server cannot allocate a new port for this client as it has
       
   444             // exhausted its relay capacity.        
       
   445             return EFalse;
       
   446 
       
   447         case E600GlobalFailure:
       
   448             return EFalse; 
       
   449 
       
   450         case ERetryAfterAddingXorOnly:
       
   451             iAddXorOnly = ETrue;
       
   452             return ETrue;
       
   453 
       
   454         default:
       
   455             return STUNUtils::Is5xxResponse( aError );
       
   456         }
       
   457 
       
   458     }
       
   459 
       
   460 // ---------------------------------------------------------------------------
       
   461 // CSTUNRelayBindingImplementation::IcmpError
       
   462 // ---------------------------------------------------------------------------
       
   463 //
       
   464 void CSTUNRelayBindingImplementation::IcmpError( const TInetAddr& aAddress )
       
   465     {
       
   466     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::IcmpError" )
       
   467     if ( iTransaction && iServerAddress.CmpAddr( aAddress ) )
       
   468         {
       
   469         //Try next address, or terminate with KErrTimedOut.
       
   470         iTransaction->Terminate( KErrTimedOut );
       
   471         }
       
   472     }
       
   473 
       
   474 // ---------------------------------------------------------------------------
       
   475 // CSTUNRelayBindingImplementation::AllocateRequestL
       
   476 // ---------------------------------------------------------------------------
       
   477 //
       
   478 void CSTUNRelayBindingImplementation::AllocateRequestL( TUint /*aRtoValue*/ )
       
   479     {
       
   480     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::AllocateRequestL" )
       
   481     iRequestType = EAllocateRequest;
       
   482     iState->SendRequestL( *this );
       
   483     }
       
   484 
       
   485 // ---------------------------------------------------------------------------
       
   486 // CSTUNRelayBindingImplementation::SetActiveDestinationRequestL
       
   487 // ---------------------------------------------------------------------------
       
   488 //
       
   489 void CSTUNRelayBindingImplementation::SetActiveDestinationRequestL( 
       
   490     const TInetAddr& aRemoteAddr, TUint32& aTimerValue )
       
   491     {
       
   492     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::SetActiveDestinationRequestL" )
       
   493     
       
   494     iRequestType = ESetActiveDestinationRequest;
       
   495     iRemoteAddr = aRemoteAddr;
       
   496     iTimerValue = NULL;
       
   497     iTimerValue = &aTimerValue;
       
   498     iState->SendRequestL( *this );
       
   499     }
       
   500 
       
   501 // ---------------------------------------------------------------------------
       
   502 // CSTUNRelayBindingImplementation::SendIndicationL
       
   503 // ---------------------------------------------------------------------------
       
   504 //
       
   505 void CSTUNRelayBindingImplementation::SendIndicationL( 
       
   506     const TInetAddr& aRemoteAddr, const TDesC8& aData, 
       
   507     TBool /*aAddFingerprint*/ )
       
   508     {
       
   509     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::SendIndicationL" )
       
   510     
       
   511     TNATFWUNSAFTransactionID transactionID;
       
   512     ClientL().ObtainTransactionIDL( transactionID );
       
   513     
       
   514     CNATFWUNSAFMessage* 
       
   515         indication = CNATFWUNSAFSendIndication::NewL( transactionID );
       
   516     CleanupStack::PushL( indication );
       
   517     
       
   518     indication->AddAttributeL( CNATFWUNSAFDataAttribute::NewLC( aData ) );
       
   519     CleanupStack::Pop(); // CNATFWUNSAFDataAttribute
       
   520     
       
   521     indication->AddAttributeL( CNATFWUNSAFRemoteAddressAttribute::NewLC( 
       
   522         aRemoteAddr ) );
       
   523     CleanupStack::Pop(); // CNATFWUNSAFRemoteAddressAttribute
       
   524     
       
   525 
       
   526     if ( iUnknownAttr )
       
   527         {
       
   528         STUNUtils::RemoveUnknownAttributes( *indication, *iUnknownAttr );
       
   529         delete iUnknownAttr;
       
   530         iUnknownAttr = NULL;
       
   531         }
       
   532         
       
   533     if ( ETcpProtocol == ClientL().TransportProtocol() )
       
   534         {
       
   535         __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::SendIndicationL TCP" )
       
   536         
       
   537         CBufBase* message = indication->EncodeL();
       
   538         CleanupStack::PushL( message );
       
   539         CNATFWUNSAFTcpRelayPacket* packet = 
       
   540             CNATFWUNSAFTcpRelayPacket::NewLC( message->Ptr( 0 ),
       
   541             CNATFWUNSAFTcpRelayPacket::EFrameTypeStun );
       
   542 
       
   543         iIndicationTx->TransmitL( *packet );
       
   544         CleanupStack::PopAndDestroy( packet );
       
   545         CleanupStack::PopAndDestroy( message );
       
   546         }
       
   547     else
       
   548         {
       
   549         iIndicationTx->TransmitL( *indication );
       
   550         }
       
   551 
       
   552     CleanupStack::PopAndDestroy( indication );
       
   553     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::SendIndicationL exit" )
       
   554     }
       
   555 
       
   556 // ---------------------------------------------------------------------------
       
   557 // CSTUNRelayBindingImplementation::ConnectRequestL
       
   558 // ---------------------------------------------------------------------------
       
   559 //
       
   560 void CSTUNRelayBindingImplementation::ConnectRequestL( 
       
   561     const TInetAddr& aRemoteAddr )
       
   562     {
       
   563     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::ConnectRequestL" )
       
   564     iRemoteAddr = aRemoteAddr;
       
   565     iRequestType = ETCPConnectRequest;
       
   566     iState->SendRequestL( *this );
       
   567     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::ConnectRequestL end" )
       
   568     }
       
   569 
       
   570 // ---------------------------------------------------------------------------
       
   571 // CSTUNRelayBindingImplementation::StreamId
       
   572 // ---------------------------------------------------------------------------
       
   573 //
       
   574 TUint CSTUNRelayBindingImplementation::StreamId() const
       
   575     {
       
   576     return iStreamId;
       
   577     }
       
   578     
       
   579 // ---------------------------------------------------------------------------
       
   580 // CSTUNRelayBindingImplementation::ConnectionId
       
   581 // ---------------------------------------------------------------------------
       
   582 //
       
   583 TUint CSTUNRelayBindingImplementation::ConnectionId() const
       
   584     {
       
   585     return iConnectionId;
       
   586     }
       
   587 
       
   588 // ---------------------------------------------------------------------------
       
   589 // CSTUNRelayBindingImplementation::CancelRequest
       
   590 // If transaction exists, delete it to stop using the socket.
       
   591 // ---------------------------------------------------------------------------
       
   592 //
       
   593 void CSTUNRelayBindingImplementation::CancelRequest()
       
   594     {
       
   595     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::CancelRequest" )
       
   596     if ( AddressResolved() )
       
   597         {
       
   598         ChangeState( *iActive );
       
   599         }
       
   600     else
       
   601         {
       
   602         //The initial request is canceled
       
   603         ChangeState( *iInit );
       
   604         }
       
   605 
       
   606     delete iTransaction;
       
   607     iTransaction = NULL;
       
   608     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::CancelRequest end" )
       
   609     }
       
   610 
       
   611 // ---------------------------------------------------------------------------
       
   612 // CSTUNRelayBindingImplementation::Socket
       
   613 // ---------------------------------------------------------------------------
       
   614 //
       
   615 const RSocket& CSTUNRelayBindingImplementation::Socket() const
       
   616     {
       
   617     return *iSocket;
       
   618     }
       
   619 
       
   620 // ---------------------------------------------------------------------------
       
   621 // CSTUNRelayBindingImplementation::AddressResolved
       
   622 // The most recent public address is kept also during a refresh.
       
   623 // ---------------------------------------------------------------------------
       
   624 //
       
   625 TBool CSTUNRelayBindingImplementation::AddressResolved() const
       
   626     {
       
   627     return !iPublicAddr.IsUnspecified();
       
   628     }
       
   629 
       
   630 // ---------------------------------------------------------------------------
       
   631 // CSTUNRelayBindingImplementation::PublicAddr
       
   632 // ---------------------------------------------------------------------------
       
   633 //
       
   634 const TInetAddr& CSTUNRelayBindingImplementation::PublicAddr() const
       
   635     {
       
   636     return iPublicAddr;
       
   637     }
       
   638     
       
   639 // ---------------------------------------------------------------------------
       
   640 // CSTUNRelayBindingImplementation::AlternateServerAddr
       
   641 // ---------------------------------------------------------------------------
       
   642 //
       
   643 const TInetAddr& CSTUNRelayBindingImplementation::AlternateServerAddr() const
       
   644     {
       
   645     return iServerAddress;
       
   646     }
       
   647     
       
   648 // ---------------------------------------------------------------------------
       
   649 // CSTUNRelayBindingImplementation::RealmFromResponse
       
   650 // ---------------------------------------------------------------------------
       
   651 //
       
   652 const HBufC8* CSTUNRelayBindingImplementation::RealmFromResponse() const
       
   653     {
       
   654     return iRealmFromResponse;
       
   655     }          
       
   656 
       
   657 // ---------------------------------------------------------------------------
       
   658 // CSTUNRelayBindingImplementation::HandleDataL
       
   659 // Must NOT leave, if aData is not a STUN message!
       
   660 // ---------------------------------------------------------------------------
       
   661 //
       
   662 HBufC8* CSTUNRelayBindingImplementation::HandleDataL(
       
   663     const TDesC8& aData, TBool& aConsumed, TInetAddr& aRemoteAddr )
       
   664     {
       
   665     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::HandleDataL" )
       
   666     aConsumed = EFalse;
       
   667     TInt err( KErrNone );
       
   668     HBufC8* dataPointer = NULL;
       
   669     CNATFWUNSAFMessage* msg = NULL;    
       
   670     CNATFWUNSAFTcpRelayPacket* relayPacket = NULL;
       
   671     
       
   672     if ( ETcpProtocol == ClientL().TransportProtocol() )
       
   673         {
       
   674         __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::HandleDataL - TCP" )
       
   675         
       
   676         TRAP( err, relayPacket = DecodeTcpRelayMessageL( aData ) );
       
   677         CleanupStack::PushL( relayPacket );
       
   678         
       
   679         if ( KErrNone == err && relayPacket && 
       
   680              CNATFWUNSAFTcpRelayPacket::EFrameTypeStun == relayPacket->Type() )
       
   681             {
       
   682             TRAP( err, msg = DecodeMessageL( relayPacket->Data() ) );
       
   683             if ( KErrNoMemory == err )
       
   684                 {
       
   685                 User::Leave( err );
       
   686                 }
       
   687             CleanupStack::PopAndDestroy( relayPacket );
       
   688             }
       
   689         else if ( relayPacket && 
       
   690                   CNATFWUNSAFTcpRelayPacket::EFrameTypeData == relayPacket->Type() )
       
   691             {
       
   692             HBufC8* ptr = relayPacket->Data().AllocL();
       
   693             CleanupStack::PopAndDestroy( relayPacket ); 
       
   694             return ptr;
       
   695             }
       
   696         else if ( KErrNoMemory == err )
       
   697             {
       
   698             User::Leave( err );
       
   699             }
       
   700         else
       
   701             {            
       
   702             __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::HandleDataL -\
       
   703                 Tcp framing invalid!" )
       
   704                 
       
   705             CleanupStack::PopAndDestroy( relayPacket );
       
   706             return NULL;
       
   707             }
       
   708         }
       
   709     else
       
   710         {
       
   711         TRAP( err, msg = DecodeMessageL( aData ) );
       
   712         if ( KErrNoMemory == err )
       
   713             {
       
   714             User::Leave( err );
       
   715             }
       
   716         }
       
   717     if ( msg )
       
   718         {
       
   719         CleanupStack::PushL( msg );
       
   720         CNATFWUNSAFRealmAttribute* realm = static_cast<CNATFWUNSAFRealmAttribute*>(
       
   721             msg->Attribute( CNATFWUNSAFAttribute::ERealm ) );          
       
   722         if ( realm )
       
   723             {
       
   724             delete iRealmFromResponse;
       
   725             iRealmFromResponse = NULL;
       
   726             const TDesC8& realmValue = ( static_cast<CNATFWUNSAFRealmAttribute*>(
       
   727                 msg->Attribute( CNATFWUNSAFAttribute::ERealm ) )->Value() );
       
   728             iRealmFromResponse = realmValue.AllocL();
       
   729             __STUNTURNCLIENT_STR8( "realm: ", *iRealmFromResponse )
       
   730             }
       
   731             
       
   732         CNATFWUNSAFNonceAttribute* nonce = static_cast<CNATFWUNSAFNonceAttribute*>(
       
   733             msg->Attribute( CNATFWUNSAFAttribute::ENonce ) );        
       
   734         if ( nonce )
       
   735             {
       
   736             delete iNonce;
       
   737             iNonce = NULL;
       
   738             const TDesC8& nonceValue = ( static_cast<CNATFWUNSAFNonceAttribute*>(
       
   739             msg->Attribute( CNATFWUNSAFAttribute::ENonce ) )->Value() );
       
   740             iNonce = nonceValue.AllocL();
       
   741             }
       
   742 
       
   743         // if aData contains data indication, decode it
       
   744         if ( msg->Type() == CNATFWUNSAFMessage::EDataIndication &&
       
   745              KErrNone == err )
       
   746             {
       
   747             const TDesC8& data = ( static_cast<CNATFWUNSAFDataAttribute*>(
       
   748                 msg->Attribute( CNATFWUNSAFAttribute::EData ) )->Value() );
       
   749 
       
   750             // Remote address is returned through reference
       
   751             CNATFWUNSAFRemoteAddressAttribute* remoteAddress =
       
   752                 static_cast<CNATFWUNSAFRemoteAddressAttribute*>
       
   753                 ( msg->Attribute( CNATFWUNSAFAttribute::ERemoteAddress ) );
       
   754 
       
   755             if( remoteAddress )
       
   756                 {
       
   757                 aRemoteAddr = remoteAddress->Address();
       
   758                 }
       
   759             else
       
   760                 {
       
   761                 remoteAddress = NULL;
       
   762                 }
       
   763 
       
   764             CNATFWUNSAFMessage* msg_unsaf = NULL;
       
   765 
       
   766             dataPointer = data.AllocLC(); // to cleanupstack
       
   767 
       
   768             TRAP( err, msg_unsaf = DecodeMessageL( *dataPointer ) );
       
   769             CleanupStack::PushL( msg_unsaf );
       
   770             if ( KErrNoMemory == err )
       
   771             	{
       
   772             	User::Leave( err );
       
   773             	}
       
   774             // if we have outstanding transaction, offer data to it
       
   775             if ( iTransaction && iRequest && !err && msg_unsaf )
       
   776                 {
       
   777                 if ( ValidateMsgType( msg_unsaf ) &&
       
   778                      iRequest->TransactionID() == msg_unsaf->TransactionID() )
       
   779                     {
       
   780                     // Data was encapsulated in data indication.
       
   781                     // Data is consumed. dataPointer is not needed.
       
   782                     aConsumed = ETrue;
       
   783                     iTransaction->ReceiveL( *msg_unsaf, *dataPointer );
       
   784                     CleanupStack::PopAndDestroy( msg_unsaf );
       
   785                     CleanupStack::PopAndDestroy( dataPointer );
       
   786                     dataPointer = NULL;
       
   787                     }
       
   788                 }
       
   789 
       
   790             if ( dataPointer )
       
   791                 {
       
   792                 // dataPointer is still valid. This means that message was not
       
   793                 // consumed, and data indication is ripped off from it.
       
   794                 // Message can also contain media data.
       
   795                 // Data indication is decapsulated out of that message.
       
   796                 CleanupStack::PopAndDestroy( msg_unsaf );
       
   797                 CleanupStack::Pop( dataPointer );
       
   798                 }
       
   799             }
       
   800 
       
   801         // Data was NOT in encapsulated in data indication, so offer
       
   802         // message to this client.
       
   803         else if ( KErrNone == err && iTransaction && iRequest )
       
   804             {
       
   805             if ( ValidateMsgType( msg ) &&
       
   806                  iRequest->TransactionID() == msg->TransactionID() )
       
   807                 {
       
   808                 aConsumed = ETrue;
       
   809                 iTransaction->ReceiveL( *msg, aData );
       
   810                 }
       
   811             }
       
   812         else
       
   813             {
       
   814             // for PCLint approval
       
   815             }
       
   816         CleanupStack::PopAndDestroy( msg );
       
   817         }
       
   818 
       
   819     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::HandleDataL end" )
       
   820 
       
   821     // if there is not any outstanding transaction, data does not belong
       
   822     // to this client. Pointer to decoded data IS NOT returned.
       
   823     return dataPointer;
       
   824     }
       
   825 
       
   826 
       
   827 // ---------------------------------------------------------------------------
       
   828 // CSTUNRelayBindingImplementation::STUNClient
       
   829 // ---------------------------------------------------------------------------
       
   830 //
       
   831 const CSTUNClient* CSTUNRelayBindingImplementation::STUNClient() const
       
   832     {
       
   833     return iClient ? &iClient->STUNClient() : NULL;
       
   834     }
       
   835 
       
   836 // ---------------------------------------------------------------------------
       
   837 // CSTUNRelayBindingImplementation::GetServerAddressL
       
   838 // ---------------------------------------------------------------------------
       
   839 //
       
   840 void CSTUNRelayBindingImplementation::GetServerAddressL()
       
   841     {
       
   842     __ASSERT_ALWAYS( iServerAddress.IsUnspecified(),
       
   843      User::Leave( KErrAlreadyExists ) );
       
   844     __ASSERT_ALWAYS( ClientL().ObtainServerAddress( iServerAddress ),
       
   845      User::Leave( KErrNotFound ) );
       
   846     }
       
   847 
       
   848 // ---------------------------------------------------------------------------
       
   849 // CSTUNRelayBindingImplementation::GetSharedSecretL
       
   850 // ---------------------------------------------------------------------------
       
   851 //
       
   852 void CSTUNRelayBindingImplementation::GetSharedSecretL()
       
   853     {
       
   854     ClientL().ObtainSharedSecretL( iBinding );
       
   855     }
       
   856 
       
   857 // ---------------------------------------------------------------------------
       
   858 // CSTUNRelayBindingImplementation::Username
       
   859 // ---------------------------------------------------------------------------
       
   860 //
       
   861 const TDesC8& CSTUNRelayBindingImplementation::Username() const
       
   862     {
       
   863     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::Username" )
       
   864     if ( iRequest && iRequest->HasAttribute( CNATFWUNSAFAttribute::EUsername ) )
       
   865         {
       
   866         return static_cast<CNATFWUNSAFUsernameAttribute*>(
       
   867         iRequest->Attribute( CNATFWUNSAFAttribute::EUsername ) )->Value();
       
   868         }
       
   869 
       
   870     return KNullDesC8;
       
   871     }
       
   872 
       
   873 // ---------------------------------------------------------------------------
       
   874 // CSTUNRelayBindingImplementation::DetachClient
       
   875 // ---------------------------------------------------------------------------
       
   876 //
       
   877 void CSTUNRelayBindingImplementation::DetachClient()
       
   878     {
       
   879     iClient = NULL;
       
   880     }
       
   881 
       
   882 // ---------------------------------------------------------------------------
       
   883 // CSTUNRelayBindingImplementation::StoreAddressL
       
   884 // Transaction no longer needed.
       
   885 // ---------------------------------------------------------------------------
       
   886 //
       
   887 void CSTUNRelayBindingImplementation::StoreAddressL( 
       
   888     const TInetAddr& aReflexiveAddr,
       
   889     const TInetAddr& aRelayAddr )
       
   890     {
       
   891     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::StoreAddressL" )
       
   892     
       
   893     iErrorResponseCount = 0;
       
   894     iPublicAddr = aReflexiveAddr;
       
   895     iRelayAddr = aRelayAddr;
       
   896     ClientL().AddressResolvedL( iBinding );
       
   897 
       
   898     FreeRequestData();
       
   899     
       
   900     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::StoreAddressL end" )
       
   901     }
       
   902 
       
   903 // ---------------------------------------------------------------------------
       
   904 // CSTUNRelayBindingImplementation::StoreAddressL
       
   905 // Transaction no longer needed.
       
   906 // This is kind of wrong functionality if this method get called.
       
   907 // ---------------------------------------------------------------------------
       
   908 //
       
   909 void CSTUNRelayBindingImplementation::StoreAddressL( 
       
   910     const TInetAddr& aPublicAddress )
       
   911     {
       
   912     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::StoreAddressL" )
       
   913     
       
   914     iErrorResponseCount = 0;
       
   915     iPublicAddr = aPublicAddress;
       
   916     ClientL().AddressResolvedL( iBinding );
       
   917 
       
   918     FreeRequestData();
       
   919     
       
   920     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::StoreAddressL end" )
       
   921     }
       
   922 
       
   923 // -----------------------------------------------------------------------------
       
   924 // CSTUNRelayBindingImplementation::ChangeState
       
   925 // -----------------------------------------------------------------------------
       
   926 //
       
   927 void CSTUNRelayBindingImplementation::ChangeState( 
       
   928     CSTUNBindingState& aNewState )
       
   929     {
       
   930     iState = &aNewState;
       
   931     }
       
   932 
       
   933 // ---------------------------------------------------------------------------
       
   934 // CSTUNRelayBindingImplementation::Terminate
       
   935 // Binding can be re-started with SendRequestL.
       
   936 // ---------------------------------------------------------------------------
       
   937 //
       
   938 void CSTUNRelayBindingImplementation::Terminate( TInt aError )
       
   939     {
       
   940     __STUNTURNCLIENT_INT1( "CSTUNRelayBindingImplementation::Terminate, error:", aError )
       
   941     __STUN_ASSERT_RETURN( aError != KErrNone, KErrArgument );
       
   942 
       
   943     NATFWUNSAF_INTLOG( "STUNRelayBinding terminated, reason", aError )
       
   944 
       
   945     TInetAddr emptyAddr;
       
   946     iPublicAddr = emptyAddr;
       
   947     iServerAddress = emptyAddr;
       
   948     iAddXorOnly = EFalse;
       
   949     iErrorResponseCount = 0;
       
   950     FreeRequestData();
       
   951 
       
   952     if ( iState != iInit )
       
   953         {
       
   954         __STUNTURNCLIENT( "Binding terminated" )
       
   955         
       
   956         ChangeState( *iInit );
       
   957         TRAP_IGNORE( ClientL().BindingErrorL( Binding(), aError, ETrue ) )
       
   958         }
       
   959     }
       
   960 
       
   961 // ---------------------------------------------------------------------------
       
   962 // CSTUNRelayBindingImplementation::FreeRequestData
       
   963 // ---------------------------------------------------------------------------
       
   964 //
       
   965 void CSTUNRelayBindingImplementation::FreeRequestData()
       
   966     {
       
   967     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::FreeRequestData" )
       
   968     delete iTransaction;
       
   969     iTransaction = NULL;
       
   970     delete iUnknownAttr;
       
   971     iUnknownAttr = NULL;
       
   972     delete iRequest;
       
   973     iRequest = NULL;
       
   974     delete iSharedSecret;
       
   975     iSharedSecret = NULL;
       
   976     delete iRealmFromResponse;
       
   977     iRealmFromResponse = NULL;
       
   978     delete iNonce;
       
   979     iNonce = NULL;    
       
   980     iRequestType = EUnknown;
       
   981     iRemoteAddr.SetAddress( KAFUnspec );
       
   982     iICEAttributes = TICEAttributes();
       
   983     
       
   984     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::FreeRequestData end" )
       
   985     }
       
   986 
       
   987 // ---------------------------------------------------------------------------
       
   988 // CSTUNRelayBindingImplementation::IsWaitingSharedSecret
       
   989 // ---------------------------------------------------------------------------
       
   990 //
       
   991 TBool CSTUNRelayBindingImplementation::IsWaitingSharedSecret() const
       
   992     {
       
   993     return iState == iGetSharedSecret;
       
   994     }
       
   995 
       
   996 // ---------------------------------------------------------------------------
       
   997 // CSTUNRelayBindingImplementation::SharedSecretObtainedL
       
   998 // ---------------------------------------------------------------------------
       
   999 //
       
  1000 void CSTUNRelayBindingImplementation::SharedSecretObtainedL( 
       
  1001     const TDesC8& aUsername, const TDesC8& aPassword )
       
  1002     {
       
  1003     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::SharedSecretObtainedL" )
       
  1004     __STUN_ASSERT_L( ( aUsername.Length() > 0 && aPassword.Length() > 0 ) ||
       
  1005      ( aUsername.Length() == 0 && aPassword.Length() == 0 ), KErrArgument );
       
  1006     
       
  1007     
       
  1008     iState->SharedSecretObtainedL( *this, aUsername, aPassword );
       
  1009     
       
  1010     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::SharedSecretObtainedL end" )
       
  1011     }
       
  1012 
       
  1013 // ---------------------------------------------------------------------------
       
  1014 // CSTUNRelayBindingImplementation::CreateBindingRequestL
       
  1015 // ---------------------------------------------------------------------------
       
  1016 //
       
  1017 void CSTUNRelayBindingImplementation::CreateBindingRequestL( 
       
  1018     const TDesC8& aUsername, const TDesC8& aPassword )
       
  1019     {
       
  1020     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::CreateBindingRequestL" )
       
  1021     
       
  1022     delete iRequest;
       
  1023     iRequest = NULL;
       
  1024 
       
  1025     if ( IsSharedSecretRequired() &&
       
  1026          ( aUsername.Length() == 0 || aPassword.Length() == 0 ) )
       
  1027          {
       
  1028          Terminate( KErrAccessDenied );
       
  1029          User::Leave( KErrAccessDenied );
       
  1030          }
       
  1031     iTransactionError = KErrNone;
       
  1032 
       
  1033     HBufC8* newSharedSecret = aPassword.AllocL();
       
  1034     delete iSharedSecret;
       
  1035     iSharedSecret = newSharedSecret;
       
  1036 
       
  1037     TNATFWUNSAFTransactionID transactionID;
       
  1038     ClientL().ObtainTransactionIDL( transactionID );
       
  1039     
       
  1040     // Check the request type
       
  1041     switch( iRequestType )
       
  1042         {
       
  1043         case ESendRequest:
       
  1044             __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::\
       
  1045             CreateBindingRequestL - BindingRequest" )
       
  1046             iRequest = CNATFWUNSAFBindingRequest::NewL( transactionID );
       
  1047             break;
       
  1048             
       
  1049         case EAllocateRequest:
       
  1050             __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::\
       
  1051             CreateBindingRequestL - AllocateRequest" )
       
  1052             iRequest = CNATFWUNSAFAllocateRequest::NewL( transactionID );
       
  1053             break;
       
  1054                         
       
  1055         case ETCPConnectRequest:
       
  1056             __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::\
       
  1057             CreateBindingRequestL - ConnectRequest" )
       
  1058             iRequest = CNATFWUNSAFConnectRequest::NewL( transactionID );
       
  1059             break;
       
  1060             
       
  1061         case ESetActiveDestinationRequest:
       
  1062             __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::\
       
  1063             CreateBindingRequestL - SetActiveDestinationRequest" )
       
  1064             iRequest = CNATFWUNSAFSetActiveDestinationRequest::NewL( 
       
  1065                 transactionID );
       
  1066             break;
       
  1067             
       
  1068         // request not recognised
       
  1069         default:
       
  1070             User::Leave( KErrArgument );
       
  1071         }
       
  1072 
       
  1073 
       
  1074     if ( aUsername.Length() > 0 )
       
  1075         {
       
  1076         __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::\
       
  1077         CreateBindingRequestL - Add USERNAME attribute" )
       
  1078         iRequest->AddAttributeL( CNATFWUNSAFUsernameAttribute::NewLC( 
       
  1079             aUsername ) );
       
  1080         CleanupStack::Pop(); // CNATFWUNSAFUsernameAttribute
       
  1081         }
       
  1082 
       
  1083     if ( iICEAttributes.iPriority > 0 )
       
  1084         {
       
  1085         __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::\
       
  1086         CreateBindingRequestL - Add PRIORITY attribute" )
       
  1087         iRequest->AddAttributeL( CNATFWUNSAFPriorityAttribute::NewLC( 
       
  1088             iICEAttributes.iPriority ) );
       
  1089         CleanupStack::Pop(); // CNATFWUNSAFPriorityAttribute
       
  1090         }
       
  1091     
       
  1092     if ( iICEAttributes.iUseCandidate )
       
  1093         {
       
  1094         __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::\
       
  1095         CreateBindingRequestL - Add USE_CANDIDATE attribute" )
       
  1096         iRequest->AddAttributeL( CNATFWUNSAFUseCandidateAttribute::NewLC() );
       
  1097         CleanupStack::Pop(); // CNATFWUNSAFUseCandidateAttribute
       
  1098         }
       
  1099     
       
  1100     if ( iICEAttributes.iControlled > 0 )
       
  1101         {
       
  1102         __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::\
       
  1103         CreateBindingRequestL - Add CONTROLLED attribute" )
       
  1104         iRequest->AddAttributeL( CNATFWUNSAFIceControlledAttribute::NewLC( 
       
  1105             iICEAttributes.iControlled ) );
       
  1106         CleanupStack::Pop(); // CNATFWUNSAFIceControlledAttribute
       
  1107         }
       
  1108         
       
  1109     if ( iICEAttributes.iControlling > 0 )
       
  1110         {
       
  1111         __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::\
       
  1112         CreateBindingRequestL - Add CONTROLLING attribute" )
       
  1113         iRequest->AddAttributeL( CNATFWUNSAFIceControllingAttribute::NewLC( 
       
  1114             iICEAttributes.iControlling ) );
       
  1115         CleanupStack::Pop(); // CNATFWUNSAFIceControllingAttribute
       
  1116         }
       
  1117     
       
  1118     if ( !iRemoteAddr.IsUnspecified() )
       
  1119         {
       
  1120         __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::\
       
  1121         CreateBindingRequestL - Add REMOTEADDRESS attribute" )
       
  1122         iRequest->AddAttributeL( CNATFWUNSAFRemoteAddressAttribute::NewLC( 
       
  1123             iRemoteAddr ) );
       
  1124         CleanupStack::Pop(); // CNATFWUNSAFRemoteAddressAttribute
       
  1125         }
       
  1126     
       
  1127     if ( iUseRealmFromResponse )
       
  1128         {
       
  1129         iRequest->AddAttributeL( CNATFWUNSAFRealmAttribute::NewLC(
       
  1130             *iRealmFromResponse ) );
       
  1131        
       
  1132         CleanupStack::Pop(); // CNATFWUNSAFRealmAttribute
       
  1133         }
       
  1134         
       
  1135     if ( iUnknownAttr )
       
  1136         {
       
  1137         STUNUtils::RemoveUnknownAttributes( *iRequest, *iUnknownAttr );
       
  1138         delete iUnknownAttr;
       
  1139         iUnknownAttr = NULL;
       
  1140         }
       
  1141         
       
  1142     if ( iNonce )
       
  1143         {
       
  1144         __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::\
       
  1145         CreateBindingRequestL - Add NONCE attribute" )
       
  1146         
       
  1147         iRequest->AddAttributeL( CNATFWUNSAFNonceAttribute::NewLC(
       
  1148             *iNonce ) );
       
  1149         CleanupStack::Pop(); // CNATFWUNSAFNonceAttribute        
       
  1150         }                     
       
  1151 
       
  1152     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::\
       
  1153     CreateBindingRequestL, exit" )
       
  1154     }
       
  1155 
       
  1156 // ---------------------------------------------------------------------------
       
  1157 // CSTUNRelayBindingImplementation::SendBindingRequestL
       
  1158 // ---------------------------------------------------------------------------
       
  1159 //
       
  1160 void CSTUNRelayBindingImplementation::SendBindingRequestL()
       
  1161     {
       
  1162     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::SendBindingRequestL" )
       
  1163     
       
  1164     __STUN_ASSERT_L( !iTransaction, KErrAlreadyExists );
       
  1165     __STUN_ASSERT_L( iRequest && iSharedSecret, KErrNotFound );
       
  1166     // Happens if resolving returned unspecified address
       
  1167     
       
  1168     if ( iSocket )
       
  1169         {
       
  1170         // old way to do it
       
  1171         iTransaction = CSTUNTransaction::NewL( *iRequest,
       
  1172                                                iServerAddress,
       
  1173                                                *iSharedSecret,
       
  1174                                                *iSocket,
       
  1175                                                ClientL().TimerProvider(),
       
  1176                                                ClientL().RetransmitInterval(),
       
  1177                                                *this,
       
  1178                                                KStunRelay,
       
  1179                                                ClientL().TransportProtocol() );
       
  1180         }
       
  1181 
       
  1182     else
       
  1183         {
       
  1184         // New way, to be used
       
  1185         iTransaction = CSTUNTransaction::NewL( *iRequest,
       
  1186                                                iServerAddress,
       
  1187                                                *iSharedSecret,
       
  1188                                                iStreamId,
       
  1189                                                iConnectionId,
       
  1190                                                ClientL().TimerProvider(),
       
  1191                                                ClientL().RetransmitInterval(),
       
  1192                                                *this,
       
  1193                                                KStunRelay,
       
  1194                                                *iMux,
       
  1195                                                ClientL().TransportProtocol() );
       
  1196         }
       
  1197 
       
  1198     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::SendBindingRequestL end" )
       
  1199     }
       
  1200 
       
  1201 // ---------------------------------------------------------------------------
       
  1202 // CSTUNRelayBindingImplementation::WaitBeforeRetrying
       
  1203 // ---------------------------------------------------------------------------
       
  1204 //
       
  1205 void CSTUNRelayBindingImplementation::WaitBeforeRetrying()
       
  1206     {
       
  1207     StartTimer( STUNUtils::EWaitBeforeRetryDuration );
       
  1208     }
       
  1209 
       
  1210 // ---------------------------------------------------------------------------
       
  1211 // CSTUNRelayBindingImplementation::SetICESpecificAttributes
       
  1212 // ---------------------------------------------------------------------------
       
  1213 //
       
  1214 void CSTUNRelayBindingImplementation::SetICESpecificAttributes( 
       
  1215     const TICEAttributes& aAttributes )
       
  1216     {
       
  1217     iICEAttributes = aAttributes;
       
  1218     }
       
  1219 
       
  1220 
       
  1221 // ---------------------------------------------------------------------------
       
  1222 // CSTUNRelayBindingImplementation::Binding
       
  1223 // ---------------------------------------------------------------------------
       
  1224 //
       
  1225 const CBinding& CSTUNRelayBindingImplementation::Binding()
       
  1226     {
       
  1227     return iBinding;
       
  1228     }
       
  1229 
       
  1230 // ---------------------------------------------------------------------------
       
  1231 // CSTUNRelayBindingImplementation::RelayAddr
       
  1232 // ---------------------------------------------------------------------------
       
  1233 //
       
  1234 const TInetAddr& CSTUNRelayBindingImplementation::RelayAddr() const 
       
  1235     {
       
  1236     __STUNTURNCLIENT( "CSTUNRelayBindingImplementation::RelayAddr" )
       
  1237     
       
  1238     return iRelayAddr;
       
  1239     }
       
  1240 
       
  1241 // ---------------------------------------------------------------------------
       
  1242 // CSTUNRelayBindingImplementation::IsSharedSecretRequired
       
  1243 // ---------------------------------------------------------------------------
       
  1244 //
       
  1245 TBool CSTUNRelayBindingImplementation::IsSharedSecretRequired() const
       
  1246     {
       
  1247     return iTransactionError == E401Unauthorized || 
       
  1248        iTransactionError == E430StaleCredentials || 
       
  1249        iTransactionError == E431IntegrityCheckFailure || 
       
  1250        iTransactionError == E432MissingUsername ||
       
  1251        iTransactionError == E433UseTLS ||
       
  1252        iTransactionError == E434MissingRealm;
       
  1253     }
       
  1254 
       
  1255 // ---------------------------------------------------------------------------
       
  1256 // CSTUNRelayBindingImplementation::ClientL
       
  1257 // ---------------------------------------------------------------------------
       
  1258 //
       
  1259 MSTUNBindingObserver& CSTUNRelayBindingImplementation::ClientL() const
       
  1260     {
       
  1261     __ASSERT_ALWAYS( iClient, User::Leave( KErrNotFound ) );
       
  1262 
       
  1263     return *iClient;
       
  1264     }
       
  1265 
       
  1266 // ---------------------------------------------------------------------------
       
  1267 // CSTUNRelayBindingImplementation::DecodeMessageL
       
  1268 // ---------------------------------------------------------------------------
       
  1269 //
       
  1270 CNATFWUNSAFMessage*
       
  1271     CSTUNRelayBindingImplementation::DecodeMessageL( const TDesC8& aData ) const
       
  1272     {
       
  1273     CNATFWUNSAFMessageFactory* decoder = CNATFWUNSAFMessageFactory::NewLC();
       
  1274     CNATFWUNSAFMessage* msg = decoder->DecodeL( aData );
       
  1275     CleanupStack::PopAndDestroy( decoder );
       
  1276     return msg;
       
  1277     }
       
  1278     
       
  1279 // ---------------------------------------------------------------------------
       
  1280 // CSTUNRelayBindingImplementation::DecodeTcpRelayMessageL
       
  1281 // ---------------------------------------------------------------------------
       
  1282 //
       
  1283 CNATFWUNSAFTcpRelayPacket*
       
  1284     CSTUNRelayBindingImplementation::DecodeTcpRelayMessageL( const TDesC8& aData ) const
       
  1285     {
       
  1286     CNATFWUNSAFTcpRelayPacketFactory* decoder = 
       
  1287                                     CNATFWUNSAFTcpRelayPacketFactory::NewLC();
       
  1288     CNATFWUNSAFTcpRelayPacket* msg = decoder->DecodeL( aData );
       
  1289     CleanupStack::PopAndDestroy( decoder );
       
  1290     return msg;
       
  1291     }    
       
  1292 
       
  1293 // ---------------------------------------------------------------------------
       
  1294 // CSTUNRelayBindingImplementation::ValidateMsgType
       
  1295 // ---------------------------------------------------------------------------
       
  1296 //
       
  1297 TBool CSTUNRelayBindingImplementation::ValidateMsgType( 
       
  1298     CNATFWUNSAFMessage* aMsg ) const
       
  1299     {
       
  1300     if ( aMsg )
       
  1301         {
       
  1302         return ( aMsg->Type() == CNATFWUNSAFMessage::EBindingResponse ||
       
  1303              aMsg->Type() == CNATFWUNSAFMessage::EAllocateResponse ||
       
  1304              aMsg->Type() == CNATFWUNSAFMessage::EBindingErrorResponse ||
       
  1305              aMsg->Type() == CNATFWUNSAFMessage::EAllocateErrorResponse ||
       
  1306              aMsg->Type() == CNATFWUNSAFMessage::EConnectResponse ||
       
  1307              aMsg->Type() == CNATFWUNSAFMessage::EConnectErrorResponse ||
       
  1308              aMsg->Type() == 
       
  1309                 CNATFWUNSAFMessage::ESetActiveDestinationResponse ||
       
  1310              aMsg->Type() == 
       
  1311                 CNATFWUNSAFMessage::ESetActiveDestinationErrorResponse );
       
  1312         }
       
  1313     return EFalse;
       
  1314     }
       
  1315 
       
  1316