diff -r 000000000000 -r 33413c0669b9 vpnengine/kmdserver/src/kmdsession.cpp --- /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 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 ); + } + } +