vpnengine/ikesocket/src/ikeconnection.cpp
changeset 0 33413c0669b9
child 8 032d3a818f49
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 2008-2009 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:  IKE socket connection
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "ikeconnection.h"
       
    20 #include "datatransfer.h"
       
    21 #include "localaddressresolver.h"
       
    22 #include "ikedebug.h"
       
    23 #include "ikesocketassert.h"
       
    24 
       
    25 // ======== MEMBER FUNCTIONS ========
       
    26 
       
    27 // ---------------------------------------------------------------------------
       
    28 // Two-phased constructor.
       
    29 // ---------------------------------------------------------------------------
       
    30 //
       
    31 CIkeConnection* CIkeConnection::NewL( MIkeDebug& aDebug )
       
    32     {
       
    33     CIkeConnection* self = new (ELeave) CIkeConnection( aDebug );  
       
    34     CleanupStack::PushL(self);
       
    35     self->ConstructL();
       
    36     CleanupStack::Pop(self);    
       
    37     return self;            
       
    38     }
       
    39 
       
    40 // ---------------------------------------------------------------------------
       
    41 // Destructor.
       
    42 // ---------------------------------------------------------------------------
       
    43 //
       
    44 CIkeConnection::~CIkeConnection()
       
    45     {
       
    46     DEBUG_LOG1( _L("CIkeConnection::~CIkeConnection this=0x%x"), this );
       
    47 
       
    48     if ( iDataTransfer )
       
    49         {
       
    50         iDataTransfer->CloseSockets();
       
    51         }
       
    52         
       
    53     DoCancelResolveFQDNAddress();
       
    54     DoCancelStartConnection();
       
    55                 
       
    56     delete iLocalAddressResolver;
       
    57     delete iDataTransfer;
       
    58     delete iLinkObserver;
       
    59     
       
    60     iConnection.Close();
       
    61     iSocketServer.Close();    
       
    62     }
       
    63 
       
    64 // ---------------------------------------------------------------------------
       
    65 // Constructor.
       
    66 // ---------------------------------------------------------------------------
       
    67 //
       
    68 CIkeConnection::CIkeConnection( MIkeDebug& aDebug )
       
    69  : CIkeConnectionInterface( EPriorityStandard ),
       
    70    iState( EIdle ),
       
    71    iExtendedPrefs(),
       
    72    iDebug( aDebug )
       
    73     {
       
    74     CActiveScheduler::Add( this ); // Added to the Active Scheduler
       
    75     }
       
    76 
       
    77 // ---------------------------------------------------------------------------
       
    78 // Second phase construction.
       
    79 // ---------------------------------------------------------------------------
       
    80 //
       
    81 void CIkeConnection::ConstructL()
       
    82     {
       
    83     DEBUG_LOG1( _L("CIkeConnection::ConstructL, this=0x%x"), this );    
       
    84     
       
    85     User::LeaveIfError( iSocketServer.Connect() );    
       
    86     iLocalAddressResolver = CLocalAddressResolver::NewL( iSocketServer,
       
    87                                                          iConnection,
       
    88                                                          iDebug );    
       
    89     iDataTransfer = CDataTransfer::NewL( iSocketServer,
       
    90                                          iConnection,
       
    91                                          *iLocalAddressResolver,
       
    92                                          *this,
       
    93                                          iDebug );    
       
    94     iLinkObserver = CConnObserver::NewL( iConnection,
       
    95                                          *this,
       
    96                                          iDebug );    
       
    97     }
       
    98 
       
    99 // ---------------------------------------------------------------------------
       
   100 // Opens data interface.
       
   101 // ---------------------------------------------------------------------------
       
   102 //
       
   103 MIkeDataInterface& CIkeConnection::OpenDataInterfaceL( const TIkeMajorVersion aIkeMajorVersion,
       
   104                                                        const TIpVersion aIpVersion )
       
   105     {        
       
   106     IKESOCKET_ASSERT( aIpVersion == EIPv4 || aIpVersion == EIPv6 );
       
   107     DEBUG_LOG2( _L("CIkeConnection::OpenDataInterfaceL, IKE version=%d, IP version=%d"),
       
   108             aIkeMajorVersion, aIpVersion );
       
   109     
       
   110     // Store IP version.
       
   111     iIpVersion = aIpVersion;
       
   112     
       
   113     // Get local IP address.
       
   114     User::LeaveIfError( iLocalAddressResolver->RefreshLocalAddresses() );    
       
   115     TBool hasIPAddr = iLocalAddressResolver->HasIPAddr( aIpVersion );
       
   116     if ( !hasIPAddr )
       
   117         {
       
   118         User::Leave( KErrNotFound );
       
   119         }
       
   120     TInetAddr localIp = iLocalAddressResolver->IPAddr( aIpVersion );
       
   121     
       
   122     // Open sockets.
       
   123     User::LeaveIfError( iDataTransfer->OpenSockets( localIp ) );                  
       
   124     
       
   125     // Set IKE major version.
       
   126     iDataTransfer->SetIkeMajorVersion( aIkeMajorVersion );
       
   127 
       
   128     // Set IP version
       
   129     iDataTransfer->SetIpVersion( aIpVersion );
       
   130     
       
   131     DEBUG_LOG( _L("Data interface open.") );
       
   132     
       
   133     // Return data interface.
       
   134     return *iDataTransfer;
       
   135     }
       
   136 
       
   137 // ---------------------------------------------------------------------------
       
   138 // Starts connection.
       
   139 // ---------------------------------------------------------------------------
       
   140 //
       
   141 void CIkeConnection::StartConnection( const TUint32 aIapId,
       
   142                                       const TUint32 aSnapId,
       
   143                                       TRequestStatus& aStatus,
       
   144                                       const TBool aForcedRoaming )
       
   145     {
       
   146     IKESOCKET_ASSERT( iState == EIdle );
       
   147     IKESOCKET_ASSERT( iClientStatus == NULL );
       
   148 
       
   149     DEBUG_LOG3( _L("CIkeConnection::StartConnection, IAP id=%d, SNAP id=%d, forced roaming=%d"),
       
   150             aIapId, aSnapId, aForcedRoaming );    
       
   151     
       
   152     iState = EConnecting;
       
   153     
       
   154     iClientStatus = &aStatus;
       
   155     *iClientStatus = KRequestPending;
       
   156     iIapId = aIapId;
       
   157     iSnapId = aSnapId;
       
   158     
       
   159     TInt err( iConnection.Open( iSocketServer ) );
       
   160     
       
   161     if ( err == KErrNone )
       
   162         {
       
   163         // Start connection.
       
   164         if ( iSnapId ) // SNAP
       
   165             {
       
   166             TRAP( err, CreateSnapPreferencesL( iSnapId,
       
   167                                                aForcedRoaming ) );
       
   168             if ( err == KErrNone )
       
   169                 {
       
   170                 iConnection.Start( iConnPrefList, iStatus );
       
   171                 }
       
   172             }    
       
   173         else // IAP
       
   174             {
       
   175             // Create preference overrides.        
       
   176             iPrefs.SetDialogPreference( ECommDbDialogPrefDoNotPrompt );
       
   177             iPrefs.SetIapId( iIapId );        
       
   178             iConnection.Start( iPrefs, iStatus );
       
   179             }            
       
   180         }
       
   181     
       
   182     if ( err != KErrNone )
       
   183         {
       
   184         TRequestStatus* ownStatus = &iStatus;
       
   185         *ownStatus = KRequestPending;
       
   186         SetActive();
       
   187         
       
   188         User::RequestComplete( ownStatus, err );
       
   189         return;
       
   190         }
       
   191     
       
   192     SetActive();
       
   193     }
       
   194 
       
   195 // ---------------------------------------------------------------------------
       
   196 // Cancels connection starting.
       
   197 // ---------------------------------------------------------------------------
       
   198 //
       
   199 void CIkeConnection::CancelStartConnection()
       
   200     {
       
   201     DEBUG_LOG( _L("CIkeConnection::CancelStartConnection") );
       
   202     
       
   203     DoCancelStartConnection();
       
   204     }
       
   205 
       
   206 // ---------------------------------------------------------------------------
       
   207 // Stops connection.
       
   208 // ---------------------------------------------------------------------------
       
   209 //
       
   210 void CIkeConnection::StopConnection()
       
   211     {
       
   212     IKESOCKET_ASSERT( iLinkObserver );
       
   213     IKESOCKET_ASSERT( iDataTransfer );
       
   214     
       
   215     DEBUG_LOG( _L("CIkeConnection::StopConnection") );
       
   216 
       
   217     iLinkObserver->CancelNotify();
       
   218     
       
   219     CancelResolveFQDNAddress();
       
   220     CancelStartConnection();
       
   221     
       
   222     iDataTransfer->CloseSockets();
       
   223     iConnection.Close();
       
   224     
       
   225     iState = EIdle;
       
   226     }
       
   227 
       
   228 // ---------------------------------------------------------------------------
       
   229 // Resolves FQDN address.
       
   230 // ---------------------------------------------------------------------------
       
   231 //
       
   232 void CIkeConnection::ResolveFQDNAddress( const TDesC& aFQDN,
       
   233                                          TNameEntry& aNameEntry,
       
   234                                          TRequestStatus& aStatus )
       
   235     {
       
   236     IKESOCKET_ASSERT( iState == EConnected );    
       
   237     DEBUG_LOG1( _L("CIkeConnection::ResolveAddress, aFQDN=%S"), &aFQDN );
       
   238     
       
   239     iState = EResolvingFQDN;
       
   240     
       
   241     iClientStatus = &aStatus;
       
   242     *iClientStatus = KRequestPending;    
       
   243     
       
   244     TInt err = iResolver.Open( iSocketServer,
       
   245                                KAfInet,
       
   246                                KProtocolInetUdp,
       
   247                                iConnection );
       
   248     
       
   249     if ( err )
       
   250         {
       
   251         TRequestStatus* ownStatus = &iStatus;
       
   252         *ownStatus = KRequestPending;
       
   253         SetActive();
       
   254         
       
   255         User::RequestComplete( ownStatus, err );
       
   256         return;
       
   257         }
       
   258     
       
   259     iResolver.GetByName( aFQDN, aNameEntry, iStatus );
       
   260     SetActive();
       
   261     }
       
   262 
       
   263 // ---------------------------------------------------------------------------
       
   264 // Cancels FQDN address resolving.
       
   265 // ---------------------------------------------------------------------------
       
   266 //
       
   267 void CIkeConnection::CancelResolveFQDNAddress()
       
   268     {
       
   269     DEBUG_LOG( _L("CIkeConnection::CancelResolveFQDNAddress") );
       
   270     
       
   271     DoCancelResolveFQDNAddress();
       
   272     }
       
   273 
       
   274 // ---------------------------------------------------------------------------
       
   275 // Request notification about disconnection.
       
   276 // ---------------------------------------------------------------------------
       
   277 //
       
   278 void CIkeConnection::NotifyDisconnect( TRequestStatus& aStatus )
       
   279     {
       
   280     IKESOCKET_ASSERT( iClientStatusNotifyDisconnect == NULL );
       
   281     DEBUG_LOG( _L("CIkeConnection::NotifyDisconnect") );
       
   282     
       
   283     iClientStatusNotifyDisconnect = &aStatus;
       
   284     *iClientStatusNotifyDisconnect = KRequestPending;
       
   285     }
       
   286 
       
   287 // ---------------------------------------------------------------------------
       
   288 // Cancels disconnect notification request.
       
   289 // ---------------------------------------------------------------------------
       
   290 //
       
   291 void CIkeConnection::CancelNotifyDisconnect()
       
   292     {
       
   293     IKESOCKET_ASSERT( iClientStatusNotifyDisconnect );
       
   294     DEBUG_LOG( _L("CIkeConnection::CancelNotifyDisconnect") );
       
   295     
       
   296     User::RequestComplete( iClientStatusNotifyDisconnect, KErrCancel );
       
   297     iClientStatusNotifyDisconnect = NULL;
       
   298     }
       
   299 
       
   300 // ---------------------------------------------------------------------------
       
   301 // Returns IAP id.
       
   302 // ---------------------------------------------------------------------------
       
   303 //
       
   304 TUint32 CIkeConnection::IapId() const
       
   305     {
       
   306     return iIapId;
       
   307     }
       
   308 
       
   309 // ---------------------------------------------------------------------------
       
   310 // Returns Net id.
       
   311 // ---------------------------------------------------------------------------
       
   312 //
       
   313 TUint32 CIkeConnection::NetId() const
       
   314     {
       
   315     return iNetId;
       
   316     }
       
   317 
       
   318 // ---------------------------------------------------------------------------
       
   319 // Returns SNAP id.
       
   320 // ---------------------------------------------------------------------------
       
   321 //
       
   322 TUint32 CIkeConnection::SnapId() const
       
   323     {
       
   324     return iSnapId;
       
   325     }
       
   326 
       
   327 // ---------------------------------------------------------------------------
       
   328 // Gets local IP address.
       
   329 // ---------------------------------------------------------------------------
       
   330 //
       
   331 TInt CIkeConnection::GetLocalAddress( const TIpVersion aIpVersion,
       
   332                                       TInetAddr& aLocalIp )
       
   333     {
       
   334     IKESOCKET_ASSERT( aIpVersion == EIPv4 || aIpVersion == EIPv6 );
       
   335     return iLocalAddressResolver->GetLocalAddress( aIpVersion, aLocalIp );
       
   336     }
       
   337 
       
   338 // ---------------------------------------------------------------------------
       
   339 // Creates connection preferences for SNAP usage. Connection preferences
       
   340 // list is constructed.
       
   341 // ---------------------------------------------------------------------------
       
   342 //
       
   343 void CIkeConnection::CreateSnapPreferencesL( const TUint32 aSnapId,
       
   344                                              const TBool aForcedRoaming )
       
   345     {
       
   346     CleanSnapPreferences();
       
   347     
       
   348     iExtendedPrefs.SetSnapId( aSnapId );
       
   349     iExtendedPrefs.SetForcedRoaming( aForcedRoaming );
       
   350     
       
   351     iConnPrefList.AppendL( &iExtendedPrefs );  
       
   352     }
       
   353 
       
   354 // ---------------------------------------------------------------------------
       
   355 // Cleans connection preferences created for SNAP usage.
       
   356 // ---------------------------------------------------------------------------
       
   357 //
       
   358 void CIkeConnection::CleanSnapPreferences()
       
   359     {
       
   360     while( iConnPrefList.Count() > 0 )
       
   361         {
       
   362         iConnPrefList.Remove( 0 );
       
   363         }       
       
   364     }
       
   365 
       
   366 // ---------------------------------------------------------------------------
       
   367 // Updates IAP id and NET id.
       
   368 // ---------------------------------------------------------------------------
       
   369 //
       
   370 void CIkeConnection::UpdateRealIapData()
       
   371     {
       
   372     _LIT( KIapId, "IAP\\Id" );
       
   373     _LIT( KNetId, "IAP\\IAPNetwork" );
       
   374     
       
   375     iConnection.GetIntSetting( KIapId, iIapId );
       
   376     iConnection.GetIntSetting( KNetId, iNetId );
       
   377     
       
   378     DEBUG_LOG2( _L("CIkeConnection::UpdateRealIapData, IAP id=%d, NET id=%d"),
       
   379             iIapId, iNetId );
       
   380     }
       
   381 
       
   382 // ---------------------------------------------------------------------------
       
   383 // Handles completion of asynchronous request in EConnecting state.
       
   384 // ---------------------------------------------------------------------------
       
   385 //
       
   386 void CIkeConnection::DoStateAfterConnecting()
       
   387     {
       
   388     IKESOCKET_ASSERT( iLinkObserver );
       
   389     IKESOCKET_ASSERT( iState == EConnecting );
       
   390     
       
   391     CleanSnapPreferences();
       
   392 
       
   393     TInt err( iStatus.Int() );
       
   394 
       
   395     if ( err == KErrNone )
       
   396         {
       
   397         // Update IAP and Net ids.
       
   398         UpdateRealIapData();
       
   399             
       
   400         // Start observing when link is disconnected.
       
   401         iLinkObserver->NotifyDisconnect();
       
   402         
       
   403         iState = EConnected;        
       
   404         }
       
   405     else
       
   406         {        
       
   407         iConnection.Close();        
       
   408         iState = EIdle;
       
   409         }
       
   410     
       
   411     User::RequestComplete( iClientStatus, err );
       
   412     iClientStatus = NULL;
       
   413     }
       
   414 
       
   415 // ---------------------------------------------------------------------------
       
   416 // Handles completion of asynchronous request in EResolvingFQDN state.
       
   417 // ---------------------------------------------------------------------------
       
   418 //
       
   419 void CIkeConnection::DoStateAfterResolvingFQDN()
       
   420     {
       
   421     IKESOCKET_ASSERT( iState == EResolvingFQDN );
       
   422     
       
   423     // Back to connected state.
       
   424     iState = EConnected;    
       
   425     iResolver.Close();
       
   426 
       
   427     User::RequestComplete( iClientStatus, iStatus.Int() );
       
   428     iClientStatus = NULL;
       
   429     }
       
   430     
       
   431 // ---------------------------------------------------------------------------
       
   432 // Implements cancellation of connection starting.
       
   433 // ---------------------------------------------------------------------------
       
   434 //
       
   435 void CIkeConnection::DoCancelStartConnection()
       
   436     {
       
   437     if ( iState == EConnecting )
       
   438         {
       
   439         IKESOCKET_ASSERT( iClientStatus );
       
   440         
       
   441         Cancel();
       
   442         
       
   443         iState = EIdle;
       
   444         iConnection.Close();
       
   445         
       
   446         CleanSnapPreferences();
       
   447 
       
   448         User::RequestComplete( iClientStatus, KErrCancel );
       
   449         iClientStatus = NULL;
       
   450         }
       
   451     }
       
   452 
       
   453 // ---------------------------------------------------------------------------
       
   454 // Implements cancellation of FQDN address resolving.
       
   455 // ---------------------------------------------------------------------------
       
   456 //
       
   457 void CIkeConnection::DoCancelResolveFQDNAddress()
       
   458     {
       
   459     if ( iState == EResolvingFQDN )
       
   460         {
       
   461         IKESOCKET_ASSERT( iClientStatus );
       
   462         
       
   463         Cancel();
       
   464         
       
   465         iState = EConnected;
       
   466         iResolver.Close();
       
   467         
       
   468         User::RequestComplete( iClientStatus, KErrCancel );
       
   469         iClientStatus = NULL;        
       
   470         }
       
   471     }
       
   472 
       
   473 // ---------------------------------------------------------------------------
       
   474 // From CActive
       
   475 // Handles request completion event about asynchronous connection starting or
       
   476 // FQDN address resolving.
       
   477 // ---------------------------------------------------------------------------
       
   478 //
       
   479 void CIkeConnection::RunL()
       
   480     {    
       
   481     DEBUG_LOG2( _L("CIkeConnection::RunL, iState=%d, iStatus=%d"),
       
   482             iState, iStatus.Int() );
       
   483     
       
   484     switch ( iState )
       
   485         {
       
   486         case EConnecting:
       
   487             DoStateAfterConnecting();
       
   488             break;
       
   489         case EResolvingFQDN:
       
   490             DoStateAfterResolvingFQDN();
       
   491             break;
       
   492         default:
       
   493             IKESOCKET_ASSERT( EFalse );
       
   494             break;
       
   495         }    
       
   496     }
       
   497 
       
   498 // ---------------------------------------------------------------------------
       
   499 // From CActive
       
   500 // Implements cancellation of asynchronous connection starting or FQDN address
       
   501 // resolving.
       
   502 // ---------------------------------------------------------------------------
       
   503 //
       
   504 void CIkeConnection::DoCancel()
       
   505     {    
       
   506     DEBUG_LOG1( _L("CIkeConnection::DoCancel, iState=%d"),
       
   507             iState );
       
   508 
       
   509     switch ( iState )
       
   510         {
       
   511         case EConnecting:
       
   512             iConnection.Stop();
       
   513             break;
       
   514         case EResolvingFQDN:
       
   515             iResolver.Cancel();
       
   516             break;
       
   517         default:
       
   518             IKESOCKET_ASSERT( EFalse );
       
   519             break;
       
   520         }
       
   521     }
       
   522 
       
   523 // ---------------------------------------------------------------------------
       
   524 // Handles notifcation about fatal data transfer error. 
       
   525 // ---------------------------------------------------------------------------
       
   526 //
       
   527 void CIkeConnection::DataTransferError( const TInt aError,
       
   528                                         const TErrorType /*aErrorType*/ )
       
   529     {    
       
   530     DEBUG_LOG1( _L("CIkeConnection::DataTransferError, aError=%d"),
       
   531             aError );
       
   532     
       
   533     // Disconnect link and notify client about disconnection.
       
   534     LinkDisconnected( aError );    
       
   535     }
       
   536 
       
   537 // ---------------------------------------------------------------------------
       
   538 // Handles notifcation about link disconnection. 
       
   539 // ---------------------------------------------------------------------------
       
   540 //
       
   541 void CIkeConnection::LinkDisconnected( const TInt aStatus )
       
   542     {    
       
   543     // Stop connection.
       
   544     StopConnection();
       
   545     
       
   546     if ( iClientStatusNotifyDisconnect )
       
   547         {
       
   548         User::RequestComplete( iClientStatusNotifyDisconnect, aStatus );
       
   549         iClientStatusNotifyDisconnect = NULL;
       
   550         }    
       
   551     }