--- /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 );
+ }
+ }
+