vpnengine/kmdserver/src/kmdsession.cpp
changeset 0 33413c0669b9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vpnengine/kmdserver/src/kmdsession.cpp	Thu Dec 17 09:14:51 2009 +0200
@@ -0,0 +1,423 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Server side session of KMDServer
+*
+*/
+
+
+#include "ikedebug.h"
+#include "ikepolparser.h"
+#include "kmdserver.h"
+#include "kmdapi.h"
+#include "kmdserver.pan"
+
+// CLASS HEADER
+#include "kmdsession.h"
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+CKmdSession* CKmdSession::NewL( CKmdServer& aServer,
+                                MIkeDebug& aDebug )
+    {
+    CKmdSession* self = new ( ELeave ) CKmdSession( aServer, aDebug );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CKmdSession::~CKmdSession()
+    {
+    DEBUG_LOG( _L("CKmdSession::~CKmdSession") );
+    
+    DoCancelStartConnection();
+    DoCancelActivate();
+    DoCancelResolveAddress();    
+    
+    iServer.KmdSessionClosed();
+    }
+
+// ---------------------------------------------------------------------------
+// Constructor.
+// ---------------------------------------------------------------------------
+//
+CKmdSession::CKmdSession( CKmdServer& aServer,
+                          MIkeDebug& aDebug )
+ : iServer( aServer ),
+   iDebug( aDebug )
+    {
+    DEBUG_LOG( _L("CKmdSession::CKmdSession") );
+    }
+
+// ---------------------------------------------------------------------------
+// From class CSession2.
+// Handles the servicing of a client request from KMD API.
+// ---------------------------------------------------------------------------
+//
+void CKmdSession::ServiceL( const RMessage2& aMessage )
+    {        
+    switch ( aMessage.Function() ) 
+        {
+        case CKmdServer::KKmdStartConnection: 
+            {
+            DEBUG_LOG(_L("CKmdSession::ServiceL, KKmdStartConnection"));
+
+            if ( iConnectionStarter != NULL )
+                {
+                aMessage.Panic( KKmdPanicCategory,
+                                EKmdPanicRequestAlreadyPending );
+                }
+            else
+                {                    
+                __ASSERT_DEBUG( iPendingStartConnection.IsNull(),
+                                User::Invariant() );             
+                iVpnIapId = aMessage.Int0();
+                
+                // Create new VPN connection object and start connection.
+                CVpnConnection& vpnConnection = iServer.CreateVpnConnectionL( iVpnIapId );       
+                TRAPD( err, iConnectionStarter = CConnectionStarter::NewL( vpnConnection, *this ) );
+                if ( err != KErrNone )
+                    {
+                    iServer.DeleteVpnConnection( iVpnIapId );
+                    User::Leave( err );
+                    }
+                iPendingStartConnection = aMessage;                                    
+                iConnectionStarter->StartRealConnection();      
+                }
+            break;
+            }
+        case CKmdServer::KKmdCancelStartConnection:
+            {
+            DEBUG_LOG(_L("CKmdSession::ServiceL, KKmdCancelStartConnection"));
+            
+            DoCancelStartConnection();            
+            aMessage.Complete( KErrNone );
+            break;
+            }
+        case CKmdServer::KKmdActivateAsync:
+            {
+            DEBUG_LOG(_L("CKmdSession::ServiceL, KKmdActivateAsync"));
+            
+            if ( iActivationStarter != NULL )
+                {
+                aMessage.Panic( KKmdPanicCategory,
+                                EKmdPanicRequestAlreadyPending );
+                }
+            else
+                {                    
+                __ASSERT_DEBUG( iPendingActivate.IsNull(),
+                                User::Invariant() );             
+                iVpnIapId = aMessage.Int0();
+                CVpnConnection* vpnConnection = NULL;
+                TRAPD( err, vpnConnection = &iServer.GetVpnConnectionL( iVpnIapId ) );
+
+                if ( err !=  KErrNone )
+                    {
+                    __ASSERT_DEBUG( err == KErrNotFound, User::Invariant() );
+                    aMessage.Complete( KErrArgument );
+                    }
+                else
+                    {
+                    // Read VPN interface name.
+                    HBufC* vpnIfName = HBufC::NewLC( aMessage.GetDesLength( 1 ) );
+                    TPtr vpnIfNameDes = vpnIfName->Des();
+                    aMessage.ReadL( 1, vpnIfNameDes );
+                    
+                    CIkeDataArray* ikeList = CIkeDataArray::NewL( 1 );
+                    CleanupStack::PushL( ikeList );
+
+                    // Read 8 bit IKE policy data.
+                    HBufC8* ikePolicy8 = HBufC8::NewLC( aMessage.GetDesLength( 2 ) );                        
+                    TPtr8 policyDes8 = ikePolicy8->Des();
+                    aMessage.ReadL( 2, policyDes8 );                
+
+                    // Copy read IKE policy data to 16 bit buffer.
+                    HBufC* ikeConf = HBufC::NewL( policyDes8.Length() );
+                    TPtr ikeConfPtr = ikeConf->Des();
+                    ikeConfPtr.Copy( policyDes8 );
+                    CleanupStack::PopAndDestroy( ikePolicy8 );
+                    CleanupStack::PushL( ikeConf );
+                    
+                    // Parse IKE policy data.
+                    TIkeParser ikeParser( *ikeConf );
+                    ikeParser.MainParseL( ikeList );                      
+                    CleanupStack::PopAndDestroy( ikeConf );
+                    
+                    // Get first IKE policy section.
+                    CIkeData* ikeData = NULL;
+                    if (ikeList->Count() > 0)
+                        {
+                        ikeData = (*ikeList)[0];
+                        }
+                    else
+                        {
+                        User::Leave( KKmdIkePolicyFileErr );
+                        }
+                    
+                    // Start negotiation.
+                    iActivationStarter = CActivationStarter::NewL( *vpnConnection,
+                                                                   *this,
+                                                                   iServer.Debug() );                       
+                    iPendingActivate = aMessage;                    
+                    iActivationStarter->Activate( *ikeData,
+                                                  vpnIfNameDes );
+                    
+                    CleanupStack::PopAndDestroy( ikeList );
+                    CleanupStack::PopAndDestroy( vpnIfName );
+                    }
+                }
+            break;
+            }       
+        case CKmdServer::KKmdCancelActivateAsync:
+            {
+            DEBUG_LOG(_L("CKmdSession::ServiceL, KKmdCancelActivateAsync"));
+            
+            DoCancelActivate();
+            aMessage.Complete( KErrNone );
+            break;
+            }
+        case CKmdServer::KKmdStopConnection:
+            {                    
+            DEBUG_LOG(_L("CKmdSession::ServiceL, KKmdStopConnection"));
+            
+            if ( iConnectionStopper != NULL )
+                {
+                aMessage.Panic( KKmdPanicCategory,
+                                EKmdPanicRequestAlreadyPending );
+                }
+            else
+                {                    
+                __ASSERT_DEBUG( iPendingStopConnection.IsNull(),
+                                User::Invariant() );
+                
+                TUint32 vpnIapId = aMessage.Int0();
+                TKmdStopConnection::TType type = (TKmdStopConnection::TType)aMessage.Int1();
+                
+                CVpnConnection& connection = iServer.GetVpnConnectionL( vpnIapId );
+                iConnectionStopper = CConnectionStopper::NewL( connection, *this );
+                
+                iPendingStopConnection = aMessage;
+                iConnectionStopper->StopVpnConnection( type == TKmdStopConnection::EForced );
+                }
+            break;
+            }            
+        case CKmdServer::KKmdResolveAddress:
+            {
+            DEBUG_LOG(_L("CKmdSession::ServiceL, KKmdResolveAddress"));
+            
+            if ( iFqdnResolver != NULL )
+                {
+                aMessage.Panic( KKmdPanicCategory,
+                                EKmdPanicRequestAlreadyPending );
+                }
+            else
+                {
+                __ASSERT_DEBUG( iPendingFqdnResolve.IsNull(),
+                                User::Invariant() );
+                iVpnIapId = aMessage.Int0();                
+                CVpnConnection* vpnConnection = NULL;
+                TRAPD( err, vpnConnection = &iServer.GetVpnConnectionL( iVpnIapId ) );
+                if ( err !=  KErrNone )
+                    {
+                    __ASSERT_DEBUG( err == KErrNotFound, User::Invariant() );
+                    aMessage.Complete( KErrArgument );
+                    }
+                else
+                    {
+                    HBufC* fqdn = HBufC::NewLC( aMessage.GetDesLengthL( 1 ) );
+                    TPtr fqdnDes = fqdn->Des();
+                    aMessage.ReadL( 1, fqdnDes );
+                    
+                    iFqdnResolver = CFqdnResolver::NewL( *vpnConnection, *this );   
+                    iPendingFqdnResolve = aMessage;
+                    iFqdnResolver->ResolveAddress( fqdn );
+                    CleanupStack::Pop( fqdn );
+                    }
+                }
+            break;
+            }
+        case CKmdServer::KKmdCancelResolveAddress:
+            {
+            DEBUG_LOG(_L("CKmdSession::ServiceL, KKmdCancelResolveAddress"));
+            
+            DoCancelResolveAddress();
+            aMessage.Complete( KErrNone );
+            break;
+            }
+        default:
+            {
+            DEBUG_LOG1(_L("CKmdSession::ServiceL, illegal command=%d"),
+                    aMessage.Function());
+            
+            aMessage.Panic( KKmdPanicCategory, EKmdPanicIllegalCommand );
+            break;
+            }
+        }
+
+    }
+
+// ---------------------------------------------------------------------------
+// From class MConnectionStarterCallback.
+// Notification about completion of real connection starting.
+// ---------------------------------------------------------------------------
+//
+void CKmdSession::RealConnectionStarted( TInt aStatus,
+                                         TInt aRealIap,
+                                         TInt aRealNetwork )
+    {
+    DEBUG_LOG3(_L("Real connection started, status=%d, IAP id=%d, NET id=%d"),
+            aStatus, aRealIap, aRealNetwork );
+
+    __ASSERT_DEBUG( !iPendingStartConnection.IsNull(), User::Invariant() );
+    
+    delete iConnectionStarter;
+    iConnectionStarter = NULL;
+
+    if ( aStatus == KErrNone )
+        {        
+        TVpnRealConnectionParams realConfig = { aRealIap,  aRealNetwork };
+        TPckg<TVpnRealConnectionParams> realConfigPckg( realConfig );
+        
+        aStatus = iPendingStartConnection.Write( 1, realConfigPckg );
+        }
+    iPendingStartConnection.Complete( aStatus );    
+    }
+
+// ---------------------------------------------------------------------------
+// From class MConnectionStopperCallback.
+// Notification about completion of VPN connection stopping.
+// ---------------------------------------------------------------------------
+//
+void CKmdSession::VpnConnectionStopped( TInt aStatus )
+    {
+    DEBUG_LOG1(_L("VPN connection stopped, status=%d"), aStatus );
+    
+    __ASSERT_DEBUG( !iPendingStopConnection.IsNull(), User::Invariant() );
+    
+    delete iConnectionStopper;
+    iConnectionStopper = NULL;
+
+    iPendingStopConnection.Complete( aStatus );    
+    }
+
+// ---------------------------------------------------------------------------
+// From class MFqdnResolverCallback.
+// Notifies about completion of FQDN address resolving.
+// ---------------------------------------------------------------------------
+//
+void CKmdSession::AddressResolveCompleted( TInt aStatus,
+                                           TNameEntry aNameEntry )
+    {
+    DEBUG_LOG1(_L("FQDN address resolving completed, status=%d"), aStatus );
+    
+    __ASSERT_DEBUG( !iPendingFqdnResolve.IsNull(),
+                    User::Invariant() );
+    
+    delete iFqdnResolver;
+    iFqdnResolver = NULL;
+    
+    if ( aStatus == KErrNone )
+        {
+        aStatus = iPendingFqdnResolve.Write( 2, aNameEntry );
+        }
+    
+    iPendingFqdnResolve.Complete( aStatus );
+    }
+
+// ---------------------------------------------------------------------------
+// From class MActivationStarterCallback.
+// Notification about completion of activation.
+// ---------------------------------------------------------------------------
+//
+void CKmdSession::ActivationCompleted( TInt aStatus,
+                                       const TVPNAddress& aVirtualIp )
+    {
+    DEBUG_LOG1(_L("Activation completed, status=%d"), aStatus );
+    
+    __ASSERT_DEBUG( !iPendingActivate.IsNull(),
+                    User::Invariant() );
+        
+    if ( aStatus == KErrNone )
+        {
+        TVPNAddressPckg addrPkcg( aVirtualIp );
+        aStatus = iPendingActivate.Write( 3, addrPkcg );
+        }
+    iPendingActivate.Complete( aStatus );
+    
+    delete iActivationStarter;
+    iActivationStarter = NULL;    
+    }
+
+// ---------------------------------------------------------------------------
+// Cancels real connection starting.
+// ---------------------------------------------------------------------------
+//
+void CKmdSession::DoCancelStartConnection()
+    {
+    if ( iConnectionStarter )
+        {
+        __ASSERT_DEBUG( !iPendingStartConnection.IsNull(),
+                        User::Invariant() );
+
+        delete iConnectionStarter; // Cancels ongoing connection starting.
+        iConnectionStarter = NULL;
+        
+        iPendingStartConnection.Complete( KErrCancel );
+        
+        // Delete VPN connection object.
+        iServer.DeleteVpnConnection( iVpnIapId );                
+        }    
+    }
+
+// ---------------------------------------------------------------------------
+// Cancels activating.
+// ---------------------------------------------------------------------------
+//
+void CKmdSession::DoCancelActivate()
+    {
+    if ( iActivationStarter )
+        {
+        __ASSERT_DEBUG( !iPendingActivate.IsNull(),
+                        User::Invariant() );
+
+        delete iActivationStarter; // Cancels ongoing activation.
+        iActivationStarter = NULL;
+        
+        iPendingActivate.Complete( KErrCancel );
+        }    
+    }
+
+// ---------------------------------------------------------------------------
+// Cancels FQDN address resolving.
+// ---------------------------------------------------------------------------
+//
+void CKmdSession::DoCancelResolveAddress()
+    {
+    if ( iFqdnResolver )
+        {
+        __ASSERT_DEBUG( !iPendingFqdnResolve.IsNull(),
+                        User::Invariant() );                
+
+        delete iFqdnResolver; // Cancels ongoing resolving.
+        iFqdnResolver = NULL;
+        
+        iPendingFqdnResolve.Complete( KErrCancel );
+        }    
+    }
+