vpnengine/kmdserver/src/vpnconnection.cpp
changeset 0 33413c0669b9
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:  VPN connection specific structures
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <cmmanagerext.h>
       
    20 #include <cmpluginvpndef.h>
       
    21 
       
    22 #include "disconnectionobserver.h"
       
    23 #include "ikeconnectioninterface.h"
       
    24 #include "ikedebug.h"
       
    25 #include "ikeplugindefs.h"
       
    26 #include "ikepluginsessionhandler.h"
       
    27 #include "ikepolparser.h"
       
    28 #include "ikesocketdefs.h"
       
    29 #include "kmdapi.h" // For error codes
       
    30 #include "kmdserver.h"
       
    31 
       
    32 // CLASS HEADER
       
    33 #include "vpnconnection.h"
       
    34 
       
    35 // ======== MEMBER FUNCTIONS ========
       
    36 
       
    37 // ---------------------------------------------------------------------------
       
    38 // Two-phased constructor.
       
    39 // ---------------------------------------------------------------------------
       
    40 //
       
    41 CVpnConnection* CVpnConnection::NewLC( TUint32 aVpnIapId,
       
    42                                        CKmdServer& aServer,
       
    43                                        MIkeDebug& aDebug )
       
    44     {
       
    45     CVpnConnection* self = new ( ELeave ) CVpnConnection( aVpnIapId,
       
    46                                                           aServer,
       
    47                                                           aDebug );
       
    48     CleanupStack::PushL( self );
       
    49     self->ConstructL();    
       
    50     return self;
       
    51     }
       
    52 
       
    53 // ---------------------------------------------------------------------------
       
    54 // Destructor.
       
    55 // ---------------------------------------------------------------------------
       
    56 //
       
    57 CVpnConnection::~CVpnConnection()
       
    58     {
       
    59     DEBUG_LOG1( _L("CVpnConnection::~CVpnConnection, VPN IAP id=%d"),
       
    60             iVpnIapId );
       
    61 
       
    62     delete iDisconnectionObserver;
       
    63     delete iIkeConnection;   
       
    64     
       
    65     iEventMediator.Close();
       
    66     }
       
    67 
       
    68 // ---------------------------------------------------------------------------
       
    69 // Constructor.
       
    70 // ---------------------------------------------------------------------------
       
    71 //
       
    72 CVpnConnection::CVpnConnection( TUint32 aVpnIapId,
       
    73                                 CKmdServer& aServer,
       
    74                                 MIkeDebug& aDebug )
       
    75  : iServer( aServer ),
       
    76    iVpnIapId( aVpnIapId ),
       
    77    iDisconnectEventReceived( EFalse ),
       
    78    iIkePluginSessionHandler( NULL ),
       
    79    iDebug( aDebug )
       
    80     {
       
    81     DEBUG_LOG1( _L("CVpnConnection::CVpnConnection, VPN IAP id=%d"),
       
    82             iVpnIapId );
       
    83     }
       
    84 
       
    85 // ---------------------------------------------------------------------------
       
    86 // Second phase construction.
       
    87 // ---------------------------------------------------------------------------
       
    88 //
       
    89 void CVpnConnection::ConstructL()
       
    90     {    
       
    91     User::LeaveIfError( iEventMediator.Connect() );
       
    92     
       
    93     using namespace CMManager;
       
    94     
       
    95     RCmManagerExt cmManagerExt;
       
    96     cmManagerExt.OpenL();        
       
    97     CleanupClosePushL( cmManagerExt );     
       
    98 
       
    99     RCmConnectionMethodExt vpnConnectionMethod = cmManagerExt.ConnectionMethodL( iVpnIapId );
       
   100     CleanupClosePushL( vpnConnectionMethod );
       
   101 
       
   102     iVpnNetId = vpnConnectionMethod.GetIntAttributeL( ECmNetworkId );
       
   103     iRealIapId  = vpnConnectionMethod.GetIntAttributeL( EVpnIapId ); 
       
   104     iRealSnapId = vpnConnectionMethod.GetIntAttributeL( ECmNextLayerSNAPId );
       
   105 
       
   106     CleanupStack::PopAndDestroy( &vpnConnectionMethod );
       
   107     CleanupStack::PopAndDestroy( &cmManagerExt );
       
   108 
       
   109     __ASSERT_DEBUG( iRealIapId != 0 || iRealSnapId != 0, User::Invariant() );        
       
   110     
       
   111     iIkeConnection = CIkeConnectionInterface::NewL( iDebug );
       
   112     iDisconnectionObserver = CDisconnectionObserver::NewL( *iIkeConnection, *this );    
       
   113     iDisconnectionObserver->StartObserving();
       
   114     }
       
   115 
       
   116 // ---------------------------------------------------------------------------
       
   117 // Starts real network connection.
       
   118 // ---------------------------------------------------------------------------
       
   119 //    
       
   120 void CVpnConnection::StartRealConnection( TRequestStatus& aStatus )
       
   121     {
       
   122     __ASSERT_DEBUG( iRealIapId != 0 || iRealSnapId != 0, User::Invariant() );
       
   123     iIkeConnection->StartConnection( iRealIapId, iRealSnapId, aStatus );
       
   124     }
       
   125         
       
   126 // ---------------------------------------------------------------------------
       
   127 // Cancels real connection starting.
       
   128 // ---------------------------------------------------------------------------
       
   129 //    
       
   130 void CVpnConnection::CancelStartRealConnection()
       
   131     {
       
   132     iIkeConnection->CancelStartConnection();
       
   133     }
       
   134 
       
   135 // ---------------------------------------------------------------------------
       
   136 // Resolves an IP address from FQDN address.
       
   137 // ---------------------------------------------------------------------------
       
   138 //  
       
   139 void CVpnConnection::ResolveAddress( const TDesC& aFqdn,
       
   140                                      TNameEntry& aNameEntry,
       
   141                                      TRequestStatus& aStatus )
       
   142     {
       
   143     iIkeConnection->ResolveFQDNAddress( aFqdn, aNameEntry, aStatus );
       
   144     }
       
   145 
       
   146 // ---------------------------------------------------------------------------
       
   147 // Cancels resolving.
       
   148 // ---------------------------------------------------------------------------
       
   149 //  
       
   150 void CVpnConnection::CancelResolveAddress()
       
   151     {
       
   152     iIkeConnection->CancelResolveFQDNAddress();
       
   153     }    
       
   154     
       
   155 // ---------------------------------------------------------------------------
       
   156 // Starts negotiation with a remote host.
       
   157 // ---------------------------------------------------------------------------
       
   158 //  
       
   159 void CVpnConnection::NegotiateWithHost( CIkeData& aIkeData,
       
   160                                         TUint32 aVpnInterfaceIndex,
       
   161                                         IkeSocket::TIpVersion aIpVersion,
       
   162                                         TVPNAddress& aInternalAddress,
       
   163                                         TRequestStatus& aStatus )
       
   164     {  
       
   165     __ASSERT_DEBUG( iClientStatusNegotiate == NULL,
       
   166                     User::Invariant() );
       
   167         
       
   168     // Store client's request status and internal address.
       
   169     iClientStatusNegotiate = &aStatus;
       
   170     *iClientStatusNegotiate = KRequestPending;
       
   171     iClientInternalAddress = &aInternalAddress;
       
   172     
       
   173     TInt err( KErrNone );
       
   174     if ( aIkeData.iIkeVersion == KIkeV1 || aIkeData.iIkeVersion == KIkeV2 )
       
   175         {
       
   176         // Create IKE plugin session.
       
   177         iIkeVersion = aIkeData.iIkeVersion;
       
   178 
       
   179         if ( iIkePluginSessionHandler == NULL )
       
   180             {
       
   181             TRAP( err, iIkePluginSessionHandler = &iServer.CreateIkePluginSessionL( iIkeVersion,
       
   182                                                                                     aIpVersion,
       
   183                                                                                     *iIkeConnection,
       
   184                                                                                     iVpnIapId,
       
   185                                                                                     iVpnNetId,
       
   186                                                                                     aVpnInterfaceIndex,
       
   187                                                                                     aIkeData.iDnsServer.Address(),
       
   188                                                                                     *this ) );
       
   189             }
       
   190         }
       
   191     else
       
   192         {
       
   193         err = KKmdIkePolicyFileErr;
       
   194         }
       
   195     
       
   196     if ( err != KErrNone )
       
   197         {
       
   198         User::RequestComplete( iClientStatusNegotiate, err );
       
   199         iClientStatusNegotiate = NULL;
       
   200         return;
       
   201         }
       
   202         
       
   203     if ( aIkeData.iAddr.Family() == KAfInet )
       
   204         {
       
   205         aIkeData.iAddr.ConvertToV4Mapped();
       
   206         aIkeData.iMask.ConvertToV4Mapped();               
       
   207         }       
       
   208     aIkeData.iAddr.SetScope( RealNetId() );
       
   209     
       
   210     // Start negotiation.
       
   211     iIkePluginSessionHandler->NegotiateWithHost( aIkeData );                                                 
       
   212     }
       
   213 
       
   214 // ---------------------------------------------------------------------------
       
   215 // Cancels negotiation.
       
   216 // ---------------------------------------------------------------------------
       
   217 //  
       
   218 void CVpnConnection::CancelNegotiateWithHost()
       
   219     {
       
   220     DoCancelNegotiateWithHost();
       
   221     }
       
   222 
       
   223 
       
   224 // ---------------------------------------------------------------------------
       
   225 // Stops VPN connection.
       
   226 // ---------------------------------------------------------------------------
       
   227 //  
       
   228 void CVpnConnection::StopVpnConnection( TBool aSilentClose,
       
   229                                         TRequestStatus& aStatus )
       
   230     {
       
   231     __ASSERT_DEBUG( iClientStatusStopVpnConnection == NULL,
       
   232                     User::Invariant() );
       
   233         
       
   234     // Store client's request status.
       
   235     iClientStatusStopVpnConnection = &aStatus;
       
   236     *iClientStatusStopVpnConnection = KRequestPending;
       
   237 
       
   238     DoStopVpnConnection( aSilentClose );    
       
   239     }
       
   240 
       
   241 // ---------------------------------------------------------------------------
       
   242 // Cancels VPN connection stoppping. VPN Connection is stopped silently.
       
   243 // ---------------------------------------------------------------------------
       
   244 //  
       
   245 void CVpnConnection::CancelStopVpnConnection()
       
   246     {   
       
   247     DoCancelStopVpnConnection();    
       
   248     }
       
   249 
       
   250 // ---------------------------------------------------------------------------
       
   251 // Gets local address of real network interface.
       
   252 // ---------------------------------------------------------------------------
       
   253 //  
       
   254 TInt CVpnConnection::GetLocalAddress( const IkeSocket::TIpVersion aIpVersion,
       
   255                                       TInetAddr& aLocalIp )
       
   256     {
       
   257     return iIkeConnection->GetLocalAddress( aIpVersion, aLocalIp );
       
   258     }
       
   259 
       
   260 // ---------------------------------------------------------------------------
       
   261 // Returns VPN IAP Id.
       
   262 // ---------------------------------------------------------------------------
       
   263 //  
       
   264 TInt CVpnConnection::VpnIapId() const
       
   265     {
       
   266     return iVpnIapId;
       
   267     }
       
   268 
       
   269 // ---------------------------------------------------------------------------
       
   270 // Returns real IAP Id.
       
   271 // ---------------------------------------------------------------------------
       
   272 //  
       
   273 TInt CVpnConnection::RealIapId() const
       
   274     {
       
   275     return iIkeConnection->IapId();
       
   276     }
       
   277         
       
   278 // ---------------------------------------------------------------------------
       
   279 // Returns real NET Id.
       
   280 // ---------------------------------------------------------------------------
       
   281 //  
       
   282 TInt CVpnConnection::RealNetId() const
       
   283     {
       
   284     return iIkeConnection->NetId();
       
   285     }    
       
   286 
       
   287 // ---------------------------------------------------------------------------
       
   288 // From class MDisconnectionObserverCallback.
       
   289 // Notification about link disconnection. VPN connection is stopped.
       
   290 // ---------------------------------------------------------------------------
       
   291 //  
       
   292 void CVpnConnection::DisconnectIndication( TInt aStatus )
       
   293     {
       
   294     // Store disconnection status for reporting it to client.
       
   295     iDisconnectEventReceived = ETrue;
       
   296     iDisconnectionStatus = aStatus;
       
   297     
       
   298     DEBUG_LOG1( _L("Link disconnected, status=%d"),
       
   299             iDisconnectionStatus );    
       
   300 
       
   301     if ( iDisconnectionStatus == KErrNone )
       
   302         {
       
   303         iDisconnectionStatus = KErrDisconnected;
       
   304         }
       
   305     
       
   306     // Stop VPN connection silently.
       
   307     DoStopVpnConnection( ETrue );
       
   308     }
       
   309 
       
   310 // ---------------------------------------------------------------------------
       
   311 // From class MIkePluginSessionHandlerCallback.
       
   312 // Notification about completion of negotiate request.
       
   313 // ---------------------------------------------------------------------------
       
   314 //  
       
   315 void CVpnConnection::NegotiationStarted( TInt aStatus,
       
   316                                          const TVPNAddress& aInternalAddress )
       
   317     {
       
   318     __ASSERT_DEBUG( iIkePluginSessionHandler != NULL,
       
   319                     User::Invariant() );
       
   320     
       
   321     DEBUG_LOG1( _L("NegotiateWithHost completed, status=%d"),
       
   322             aStatus );
       
   323         
       
   324     // Use disconnection status for reporting if set.
       
   325     if ( iDisconnectEventReceived )
       
   326         {
       
   327         aStatus = iDisconnectionStatus;
       
   328         }
       
   329     
       
   330     if ( iClientStatusNegotiate != NULL )
       
   331         {
       
   332         *iClientInternalAddress = aInternalAddress;
       
   333         
       
   334         // Complete client's request.
       
   335         User::RequestComplete( iClientStatusNegotiate, aStatus );        
       
   336         iClientInternalAddress = NULL;
       
   337         iClientStatusNegotiate = NULL;        
       
   338         }
       
   339     }
       
   340 
       
   341 // ---------------------------------------------------------------------------
       
   342 // From class MIkePluginSessionHandlerCallback.
       
   343 // Notification about completion of delete session request. IKE plugin
       
   344 // session object is deleted and real connection stopped.
       
   345 // ---------------------------------------------------------------------------
       
   346 //  
       
   347 void CVpnConnection::IkePluginSessionClosed( TInt aStatus )
       
   348     {
       
   349     __ASSERT_DEBUG( iIkePluginSessionHandler != NULL,
       
   350                     User::Invariant() );
       
   351     
       
   352     DEBUG_LOG1( _L("IKE plugin session closed, status=%d"),
       
   353             aStatus );
       
   354 
       
   355     iServer.DeleteIkePluginSession( iIkeVersion, iVpnIapId );
       
   356     iIkePluginSessionHandler = NULL;
       
   357     
       
   358     DoStopRealConnection( aStatus );
       
   359     }
       
   360 
       
   361 // ---------------------------------------------------------------------------
       
   362 // From class MIkePluginSessionHandlerCallback.
       
   363 // Notification about IKE plugin session error.
       
   364 // ---------------------------------------------------------------------------
       
   365 //  
       
   366 void CVpnConnection::IkePluginSessionError( TInt aStatus )
       
   367     {
       
   368     // Stop VPN connection silently.
       
   369     DisconnectIndication( aStatus );
       
   370     }
       
   371 
       
   372 // ---------------------------------------------------------------------------
       
   373 // Cancels negotiation.
       
   374 // ---------------------------------------------------------------------------
       
   375 //  
       
   376 void CVpnConnection::DoCancelNegotiateWithHost()
       
   377     {
       
   378     if ( iIkePluginSessionHandler )
       
   379         {
       
   380         iIkePluginSessionHandler->CancelNegotiateWithHost();
       
   381         }
       
   382     }
       
   383 
       
   384 // ---------------------------------------------------------------------------
       
   385 // Stops VPN connection.
       
   386 // ---------------------------------------------------------------------------
       
   387 //  
       
   388 void CVpnConnection::DoStopVpnConnection( TBool aSilentClose )
       
   389     {    
       
   390     if ( iIkePluginSessionHandler == NULL )
       
   391         {
       
   392         // Stop real connection immediately.
       
   393         DoStopRealConnection( KErrNone );    
       
   394         }
       
   395     else
       
   396         {
       
   397         DoCancelNegotiateWithHost();
       
   398         
       
   399         // Delete IKE plugin session first.
       
   400         DoDeleteSession( aSilentClose );
       
   401         }                
       
   402     }
       
   403 
       
   404 // ---------------------------------------------------------------------------
       
   405 // Cancels VPN connection stopping. VPN Connection is stopped silently.
       
   406 // ---------------------------------------------------------------------------
       
   407 //  
       
   408 void CVpnConnection::DoCancelStopVpnConnection()
       
   409     {
       
   410     DoCancelDeleteSession();
       
   411     
       
   412     if ( iIkePluginSessionHandler != NULL )
       
   413         {
       
   414         iServer.DeleteIkePluginSession( iIkeVersion, iVpnIapId );
       
   415         iIkePluginSessionHandler = NULL;
       
   416         }
       
   417     
       
   418     DoStopRealConnection( KErrCancel );       
       
   419     }
       
   420 
       
   421 // ---------------------------------------------------------------------------
       
   422 // Starts deletion of IKE plugin session.
       
   423 // ---------------------------------------------------------------------------
       
   424 //  
       
   425 void CVpnConnection::DoDeleteSession( TBool aSilentClose )
       
   426     {
       
   427     __ASSERT_DEBUG( iIkePluginSessionHandler != NULL,
       
   428                     User::Invariant() );
       
   429     
       
   430     iIkePluginSessionHandler->DeleteSession( aSilentClose );
       
   431     }
       
   432 
       
   433 // ---------------------------------------------------------------------------
       
   434 // Cancels deletion of IKE plugin session. IKE plugin session is deleted
       
   435 // silently.
       
   436 // ---------------------------------------------------------------------------
       
   437 //  
       
   438 void CVpnConnection::DoCancelDeleteSession()
       
   439     {
       
   440     if ( iIkePluginSessionHandler != NULL )
       
   441         {
       
   442         iIkePluginSessionHandler->CancelDeleteSession();
       
   443         }
       
   444     }
       
   445 
       
   446 // ---------------------------------------------------------------------------
       
   447 // Stops real network connection.
       
   448 // ---------------------------------------------------------------------------
       
   449 //  
       
   450 void CVpnConnection::DoStopRealConnection( TInt aStatus )
       
   451     {
       
   452     iDisconnectionObserver->Cancel();        
       
   453     iIkeConnection->StopConnection();
       
   454     
       
   455     // Use disconnection status for reporting if set.
       
   456     if ( iDisconnectEventReceived )
       
   457         {
       
   458         aStatus = iDisconnectionStatus;
       
   459         }
       
   460 
       
   461     if ( iClientStatusStopVpnConnection )
       
   462         {
       
   463         // Complete client's request.
       
   464         User::RequestComplete( iClientStatusStopVpnConnection, aStatus );
       
   465         iClientStatusStopVpnConnection = NULL;
       
   466         }                    
       
   467     DoReportDisconnectEvent( aStatus );
       
   468         
       
   469     // Delete VPN connection object.
       
   470     iServer.DeleteVpnConnection( iVpnIapId );
       
   471     }
       
   472 
       
   473 // ---------------------------------------------------------------------------
       
   474 // Reports disconnect event via Event Mediator API.
       
   475 // ---------------------------------------------------------------------------
       
   476 //  
       
   477 void CVpnConnection::DoReportDisconnectEvent( TInt aStatus )
       
   478     {
       
   479     TPckg<TUint32> connInfoDes( iVpnIapId );
       
   480     TEventData info;
       
   481     info.iTaskStatus = aStatus;
       
   482     TPckg<TEventData> infoDes( info );
       
   483     
       
   484     DEBUG_LOG2( _L("Report disconnect event via event mediator, VPN IAP Id=%d, status=%d"),
       
   485             iVpnIapId, aStatus );
       
   486 
       
   487     iEventMediator.ReportEvent( EKmdRealIapConnDownEvent,
       
   488                                 connInfoDes,
       
   489                                 infoDes );    
       
   490     }