vpnengine/ikev2lib/src/ikev2pluginsession.cpp
changeset 0 33413c0669b9
child 10 68dc8923de26
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 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:
       
    15 *
       
    16 */
       
    17 
       
    18 #include <random.h>
       
    19 
       
    20 #include "ikev2pluginsession.h"
       
    21 #include "ikev2plugin.h"
       
    22 #include "ikev2Negotiation.h"
       
    23 #include "ikepolparser.h"
       
    24 #include "ikedebug.h"
       
    25 #include "ikev2SA.h"
       
    26 #include "ikev2SAdata.h"
       
    27 #include "ikedatainterface.h"
       
    28 #include "ipsecsadata.h"
       
    29 #include "ikev2pfkey.h"
       
    30 #include "ipsecsalist.h"
       
    31 #include "ipsecpolicyutil.h"
       
    32 #include "ikev2messagesendqueue.h"
       
    33 
       
    34 
       
    35 CIkev2PluginSession* CIkev2PluginSession::NewL( TUint32 aVpnIapId,
       
    36                                                 TUint32 aVpnNetId,
       
    37                                                 TUint32 aVpnInterfaceIndex,
       
    38                                                 MIkeDataInterface& aDataInterface,
       
    39                                                 CIkev2PlugIn& aPlugin, 
       
    40                                                 CPFKeySocketIf& aPfKeySocketIf,
       
    41                                                 CIpsecPolicyUtil& aIpsecPolicyUtil,
       
    42                                                 MKmdEventLoggerIf& aEventLogger,
       
    43                                                 MIkeDebug& aDebug )
       
    44     {
       
    45     CIkev2PluginSession* self = new (ELeave) CIkev2PluginSession( aVpnIapId, aVpnNetId, 
       
    46                                                                   aVpnInterfaceIndex, aDataInterface,
       
    47                                                                   aPlugin, aPfKeySocketIf, aIpsecPolicyUtil,
       
    48                                                                   aEventLogger, aDebug );
       
    49     CleanupStack::PushL(self);
       
    50     self->ConstructL();
       
    51     CleanupStack::Pop(self);
       
    52     
       
    53     return self;
       
    54     }
       
    55 
       
    56 
       
    57 CIkev2PluginSession::CIkev2PluginSession( TUint32 aVpnIapId,
       
    58                                           TUint32 aVpnNetId,
       
    59                                           TUint32 aVpnInterfaceIndex,
       
    60                                           MIkeDataInterface& aDataInterface,
       
    61                                           CIkev2PlugIn& aPlugin,
       
    62                                           CPFKeySocketIf& aPfKeySocketIf,
       
    63                                           CIpsecPolicyUtil& aIpsecPolicyUtil,
       
    64                                           MKmdEventLoggerIf& aEventLogger,
       
    65                                           MIkeDebug& aDebug )
       
    66 : iVpnIapId(aVpnIapId), iVpnNetId(aVpnNetId),  iDataInterface(aDataInterface), iPlugin(aPlugin), 
       
    67   iPfKeySocketIf(aPfKeySocketIf), iIpsecPolicyUtil(aIpsecPolicyUtil), iEventLogger(aEventLogger), 
       
    68   iDebug(aDebug), iVpnInterfaceIndex(aVpnInterfaceIndex) 
       
    69     {
       
    70     }
       
    71 
       
    72 
       
    73 void CIkev2PluginSession::ConstructL()
       
    74     {
       
    75     TPtr8 ptr((TUint8*)&iSAIdSeed, sizeof(iSAIdSeed));
       
    76     ptr.SetLength(sizeof(iSAIdSeed));
       
    77     TRandom::RandomL(ptr);  
       
    78     iSAIdSeed &= 0x7fffffff;  // Reset the most significant bit
       
    79     DEBUG_LOG1(_L("CIkev2Plugin::ConstructL, SAId seed: %d"), iSAIdSeed );
       
    80     }
       
    81 
       
    82 
       
    83 CIkev2PluginSession::~CIkev2PluginSession()
       
    84     {
       
    85     //Makes sure that all the negotiations and
       
    86     //Sa data structures are deleted:
       
    87     while ( iFirstNegotiation )
       
    88         {
       
    89         CIkev2Negotiation* negotiation = iFirstNegotiation;
       
    90         iFirstNegotiation = iFirstNegotiation->iNext;
       
    91         
       
    92         delete negotiation;
       
    93         }
       
    94 
       
    95     while(iFirstIkev2SA)
       
    96         {
       
    97         CIkev2SA* ikeV2Sa = iFirstIkev2SA;
       
    98         iFirstIkev2SA = ikeV2Sa->iNext;
       
    99         
       
   100         delete ikeV2Sa;
       
   101         }        
       
   102     
       
   103     delete iMessageSendQue;
       
   104     delete iReceiver;    
       
   105     delete iIkeData; 
       
   106     delete iDeactivationTimer;    
       
   107     
       
   108     iPlugin.PluginSessionDeleted(this);
       
   109     }
       
   110 
       
   111 
       
   112 void CIkev2PluginSession::NegotiateWithHost( const CIkeData& aIkeData,
       
   113                                              TVPNAddress& aInternalAddress,
       
   114                                              TRequestStatus& aStatus )
       
   115     {
       
   116     __ASSERT_DEBUG(iClientStatusNegotiate == NULL,
       
   117                    User::Invariant());
       
   118     
       
   119     iClientStatusNegotiate = &aStatus;
       
   120     *iClientStatusNegotiate = KRequestPending;
       
   121         
       
   122     iInternalAddress = &aInternalAddress;
       
   123     
       
   124     TRAPD(err, DoNegotiateWithHostL(aIkeData));
       
   125     if (err != KErrNone)
       
   126         {
       
   127         DoCompleteNegotiateWithHost(err);
       
   128         }    
       
   129     }
       
   130 
       
   131 
       
   132 void CIkev2PluginSession::DoNegotiateWithHostL( const CIkeData& aIkeData )
       
   133     {
       
   134     iIkeData = CIkeData::NewL(&aIkeData);
       
   135     
       
   136     iReceiver = CIkev2Receiver::NewL( iDataInterface,
       
   137                                       *this );   
       
   138     
       
   139     iMessageSendQue = CIkev2MessageSendQueue::NewL(iDataInterface, 
       
   140                                                    iIkeData->iAddr, 
       
   141                                                    iIkeData->iDscp,
       
   142                                                    iIkeData->iNatKeepAlive,
       
   143                                                    iDebug);    
       
   144     
       
   145     
       
   146     TInetAddr physicalAddr;
       
   147     iDataInterface.GetLocalAddress(physicalAddr);
       
   148     TInetAddr sgwAddr(iIkeData->iAddr);       
       
   149     
       
   150     // Negotiation ownership is transferred to the plugin
       
   151     // before leave can occur.
       
   152     iSAIdSeed++;
       
   153     
       
   154     if (aIkeData.iUseInternalAddr)
       
   155         {
       
   156         CIkev2Negotiation* Negotiation = CIkev2Negotiation::NewL(*this, iPfKeySocketIf, iEventLogger,
       
   157                                                                  *iMessageSendQue, iDebug, iIkeData, 
       
   158                                                                  iVpnIapId, iSAIdSeed,
       
   159                                                                  physicalAddr, sgwAddr);
       
   160 
       
   161         Negotiation->StartIkeSANegotiationL();
       
   162         }
       
   163     else
       
   164         {
       
   165         //If internall addressing is not in use, we do not do anything else
       
   166         //in this phase. The actual IKE negotiation is trickered by an Acquire
       
   167         //PFKEY message from the IPsec, when there is actual data between the SGW and
       
   168         //the phone.
       
   169         DoCompleteNegotiateWithHost( KErrNone);
       
   170         }
       
   171     }
       
   172 
       
   173 
       
   174 void CIkev2PluginSession::CancelNegotiateWithHost()
       
   175     {
       
   176     
       
   177     if (iClientStatusNegotiate != NULL)
       
   178         {
       
   179         //If the Negotiate with host is cancelled we pretty much do a silent close
       
   180         //for the connection
       
   181 
       
   182         while ( iFirstNegotiation )
       
   183             {
       
   184             CIkev2Negotiation* negotiation = iFirstNegotiation;
       
   185             iFirstNegotiation = iFirstNegotiation->iNext;
       
   186             
       
   187             delete negotiation;
       
   188             }
       
   189 
       
   190         while(iFirstIkev2SA)
       
   191             {
       
   192             CIkev2SA* ikeV2Sa = iFirstIkev2SA;
       
   193             iFirstIkev2SA = ikeV2Sa->iNext;
       
   194             
       
   195             delete ikeV2Sa;
       
   196             }
       
   197         DoCompleteNegotiateWithHost(KErrCancel);
       
   198         }            
       
   199     }
       
   200 
       
   201 
       
   202 void CIkev2PluginSession::DeleteSession( const TBool aSilentClose,
       
   203                                          TRequestStatus& aStatus )
       
   204     {
       
   205     DEBUG_LOG1(_L("Deactivating IKE SA:s for vpn iap %d"), iVpnIapId);
       
   206     
       
   207     __ASSERT_DEBUG(iClientStatusDelete == NULL, User::Invariant());
       
   208     iClientStatusDelete = &aStatus;
       
   209     *iClientStatusDelete = KRequestPending;
       
   210     
       
   211     TInt err = KErrNone;
       
   212     TBool doSilentClose = aSilentClose;
       
   213     //Deletes all ongoing ike negotiations    
       
   214     while ( iFirstNegotiation )
       
   215         {
       
   216         CIkev2Negotiation* negotiation = iFirstNegotiation;
       
   217         iFirstNegotiation = iFirstNegotiation->iNext;
       
   218         
       
   219         delete negotiation;
       
   220         }
       
   221     
       
   222     TBool deactivating = EFalse;
       
   223     while(iFirstIkev2SA)
       
   224         {
       
   225         CIkev2SA* ikeV2Sa = iFirstIkev2SA;
       
   226         iFirstIkev2SA = ikeV2Sa->iNext;
       
   227         
       
   228         if (!doSilentClose)
       
   229             {
       
   230             TRAP(err, DoDeleteIkeSAExhangeL(ikeV2Sa->iIkeV2SaData));
       
   231             if (err == KErrNone)
       
   232                 {
       
   233                 deactivating = ETrue;
       
   234                 }
       
   235             else
       
   236                 {
       
   237                 //If we can't start the IKE SA delete exhange, 
       
   238                 //we do following expection handling:
       
   239                 //1. Possible already active delete exhanges can continue as they were.
       
   240                 //2. The IKE SA, which delete exchange failured, is deleted silently.
       
   241                 //3. The rest of the IKE SAs are deleted silently.
       
   242                 //4. The caller is notified with the error returned by the failed delete 
       
   243                 //   exchange attempt, if no delete exhanges are in progress.
       
   244                 //5. If there is ongoing delete exhange(s), the caller is notified with the
       
   245                 //   status of last delete exhange, which completes.
       
   246                 DEBUG_LOG1(_L("CIkev2PluginSession::DeleteSession: Can't start IKE SA delete exhange (%d)"), 
       
   247                            err );
       
   248                 doSilentClose = ETrue;
       
   249                 }
       
   250             }
       
   251         delete ikeV2Sa;
       
   252         }
       
   253     
       
   254     if (deactivating)
       
   255         {
       
   256         TRAP( err, iDeactivationTimer = CIkev2DeactivationTimer::NewL(*this) );
       
   257         }
       
   258     
       
   259     if (deactivating &&
       
   260         err == KErrNone)
       
   261         {
       
   262         iDeactivationTimer->IssueRequest();
       
   263         }
       
   264     else
       
   265         {
       
   266         delete iIkeData;
       
   267         iIkeData = NULL;
       
   268         DoCompleteDeleteSession(err);        
       
   269         }    
       
   270     }
       
   271 
       
   272 
       
   273 void CIkev2PluginSession::DoDeleteIkeSAExhangeL(TIkev2SAData& aIkev2SAdata)
       
   274     {
       
   275     DEBUG_LOG1(_L("Deleting IKE SA SAID =  %d"), aIkev2SAdata.SaId());
       
   276                 
       
   277     __ASSERT_DEBUG(iFirstNegotiation == NULL, User::Invariant());
       
   278     
       
   279    CIkev2Negotiation* negotiation = CIkev2Negotiation::NewL(*this, iPfKeySocketIf, 
       
   280                                                             iEventLogger, *iMessageSendQue, 
       
   281                                                             iDebug, aIkev2SAdata);
       
   282    CleanupStack::PushL(negotiation);
       
   283    negotiation->StartIkeSADeleteL();
       
   284    CleanupStack::Pop(negotiation);
       
   285    
       
   286    __ASSERT_DEBUG( !negotiation->Stopped(), User::Invariant() );
       
   287 
       
   288     }
       
   289 
       
   290 
       
   291 void CIkev2PluginSession::CancelDeleteSession()
       
   292     {
       
   293     if (iClientStatusDelete != NULL)
       
   294         {
       
   295         //If the delete sessionis cancelled we pretty much do a silent close
       
   296         //for the connection
       
   297         iMessageSendQue->CancelAll();
       
   298         iReceiver->Cancel();    
       
   299         delete iDeactivationTimer;
       
   300         iDeactivationTimer = NULL;
       
   301         
       
   302         while ( iFirstNegotiation )
       
   303             {
       
   304             CIkev2Negotiation* negotiation = iFirstNegotiation;
       
   305             iFirstNegotiation = iFirstNegotiation->iNext;
       
   306             
       
   307             delete negotiation;
       
   308             }
       
   309 
       
   310         while(iFirstIkev2SA)
       
   311             {
       
   312             CIkev2SA* ikeV2Sa = iFirstIkev2SA;
       
   313             iFirstIkev2SA = ikeV2Sa->iNext;
       
   314             
       
   315             delete ikeV2Sa;
       
   316             }
       
   317         DoCompleteDeleteSession(KErrCancel);
       
   318         }            
       
   319     }
       
   320 
       
   321 
       
   322 void CIkev2PluginSession::NotifyError( TRequestStatus& aStatus )
       
   323     {
       
   324     aStatus = KRequestPending;
       
   325     iClientStatusNotifyError = &aStatus;
       
   326     }
       
   327 
       
   328 void CIkev2PluginSession::CancelNotifyError()
       
   329     {    
       
   330     if (iClientStatusNotifyError != NULL)
       
   331         {
       
   332         DoCompleteNotifyError(KErrCancel);
       
   333         }
       
   334     }
       
   335 
       
   336 
       
   337 void CIkev2PluginSession::NotifyInternalAddressChanged( TVPNAddress& aInternalAddress,
       
   338                                                         TRequestStatus& aStatus )
       
   339     {
       
   340     __ASSERT_DEBUG(iClientStatusInternalAddressChange == NULL,
       
   341                     User::Invariant());    
       
   342     
       
   343     __ASSERT_DEBUG(iChangedInternalAddress == NULL,
       
   344                     User::Invariant());    
       
   345     
       
   346 
       
   347     iClientStatusInternalAddressChange = &aStatus;
       
   348     *iClientStatusInternalAddressChange = KRequestPending;
       
   349     
       
   350     iChangedInternalAddress = &aInternalAddress;
       
   351     }
       
   352 
       
   353 
       
   354 void CIkev2PluginSession::CancelNotifyInternalAddressChanged()
       
   355     {
       
   356     if (iClientStatusInternalAddressChange != NULL)
       
   357         {
       
   358         __ASSERT_DEBUG(iChangedInternalAddress != NULL, User::Invariant());
       
   359         iChangedInternalAddress = NULL;
       
   360         User::RequestComplete(iClientStatusInternalAddressChange, KErrCancel);
       
   361         }
       
   362     }
       
   363 
       
   364 
       
   365 void CIkev2PluginSession::LinkNegotiation(CIkev2Negotiation* aNegotiation)
       
   366 {  
       
   367     ASSERT(aNegotiation); 
       
   368     aNegotiation->iNext = iFirstNegotiation;  
       
   369     iFirstNegotiation = aNegotiation; 
       
   370 }
       
   371 
       
   372 
       
   373 void CIkev2PluginSession::RemoveNegotiation(CIkev2Negotiation* aNegotiation)
       
   374     {
       
   375         CIkev2Negotiation* Prev = NULL;
       
   376         CIkev2Negotiation* Neg  = iFirstNegotiation;
       
   377         
       
   378         while ( Neg )
       
   379         {
       
   380             if ( Neg == aNegotiation )
       
   381             {
       
   382                if ( Prev )
       
   383                     Prev->iNext = Neg->iNext;
       
   384                else iFirstNegotiation = Neg->iNext;
       
   385                break;  
       
   386             }
       
   387             Prev = Neg;
       
   388             Neg  = Neg->iNext;
       
   389         }   
       
   390     }
       
   391 
       
   392 //
       
   393 // Find an IKEv2 SA using SA Id as search argument
       
   394 //
       
   395 CIkev2SA* CIkev2PluginSession::FindIkev2SA(TUint32 aSAId, TInt aRequiredState, TInt aNewState)
       
   396 {
       
   397     CIkev2SA* Sa = iFirstIkev2SA;
       
   398     while ( Sa )
       
   399     {
       
   400         if ( ( Sa->iIkeV2SaData.SaId() == aSAId )
       
   401               &&
       
   402            ( ( aRequiredState == KSaStateNotDefined) ||
       
   403              ( aRequiredState == Sa->iIkeV2SaData.iSAState ) ) )
       
   404         {
       
   405            if ( aNewState != KSaStateNotDefined )
       
   406                Sa->iIkeV2SaData.iSAState = aNewState;  
       
   407            break;
       
   408         }   
       
   409         Sa = Sa->iNext;
       
   410     }   
       
   411     return Sa;
       
   412 }
       
   413 
       
   414 
       
   415 TBool CIkev2PluginSession::UpdateIkev2SAL(TIkev2SAData* aIkev2SAData, TIkeV2IpsecSAData* aIpsecSAData)
       
   416     {
       
   417     ASSERT(aIkev2SAData);
       
   418     CIkev2SA* Ikev2SA = FindIkev2SA(aIkev2SAData->SaId(), KSaStateNotDefined, KSaStateNotDefined);
       
   419     if ( Ikev2SA )
       
   420         {
       
   421         Ikev2SA->UpdateL(aIkev2SAData, aIpsecSAData);
       
   422         return ETrue;
       
   423         }
       
   424     else 
       
   425         {
       
   426         return EFalse;
       
   427         }
       
   428     }
       
   429 
       
   430 TIkeV2IpsecSAData* CIkev2PluginSession::FindIpsecSAData(TUint32 aSAId, const TDesC8& aSpi, TBool aInbound)
       
   431     {
       
   432     __ASSERT_ALWAYS(aSpi.Length() == 4, User::Invariant());
       
   433     
       
   434     _LIT8(KZeroSpi, "");
       
   435     TIkeV2IpsecSAData* SaData = NULL;        
       
   436     CIkev2SA* Ikev2SA = FindIkev2SA(aSAId, KSaStateNotDefined, KSaStateNotDefined);
       
   437     if ( Ikev2SA )
       
   438         {
       
   439         if ( aInbound ) 
       
   440             SaData = Ikev2SA->FindIpsecSaData(aSpi, KZeroSpi, EFalse); 
       
   441         else SaData = Ikev2SA->FindIpsecSaData(KZeroSpi, aSpi, EFalse);    
       
   442         }   
       
   443     return SaData;
       
   444     }
       
   445 
       
   446 
       
   447 //
       
   448 // Delete an IKEv2 SA using SA Id as search argument
       
   449 //
       
   450 void CIkev2PluginSession::DeleteIkev2SA(TUint32 aSAId)
       
   451 {
       
   452     CIkev2SA* Sa     = iFirstIkev2SA;
       
   453     CIkev2SA* PrevSa = NULL;
       
   454     while ( Sa )
       
   455     {
       
   456         if ( Sa->iIkeV2SaData.SaId() == aSAId )
       
   457         {
       
   458             if ( PrevSa )
       
   459                 {
       
   460                 PrevSa->iNext = Sa->iNext;
       
   461                 }
       
   462             else
       
   463                 {
       
   464                 iFirstIkev2SA = Sa->iNext;
       
   465                 }
       
   466             if (Sa->iIkeV2SaData.iFloatedPort)
       
   467                 {
       
   468                 iMessageSendQue->SaBehindNatDeleted(Sa->iIkeV2SaData.SaId());
       
   469                 }
       
   470             delete Sa;
       
   471             break;
       
   472         }
       
   473         PrevSa = Sa;
       
   474         Sa     = Sa->iNext;
       
   475     }   
       
   476 }
       
   477 
       
   478 TUint32 CIkev2PluginSession::GetSAId()    
       
   479     { 
       
   480     iSAIdSeed++; 
       
   481     return iSAIdSeed; 
       
   482     }
       
   483 
       
   484 TBool CIkev2PluginSession::CreateIkev2SAL(TIkev2SAData& aIkev2SAData)
       
   485     {
       
   486     CIkev2SA* Ikev2SA = CIkev2SA::NewL(*this, aIkev2SAData, iDebug);
       
   487     if (aIkev2SAData.iFloatedPort)
       
   488         {
       
   489         CleanupStack::PushL(Ikev2SA);
       
   490         iMessageSendQue->NewSaBehindNatL(aIkev2SAData.SaId());
       
   491         CleanupStack::Pop(Ikev2SA);
       
   492         }
       
   493     Ikev2SA->iNext = iFirstIkev2SA; 
       
   494     iFirstIkev2SA = Ikev2SA; 
       
   495  
       
   496     return ETrue;
       
   497     }
       
   498 
       
   499 void CIkev2PluginSession::IkeSaCompleted(TInt aStatus, TVPNAddress& aInternalAddress)
       
   500 {       
       
   501    if (iClientStatusNegotiate != NULL)
       
   502        {
       
   503        //This is the first IKE sa of this session
       
   504        if (!aInternalAddress.iVPNIfAddr.IsUnspecified())
       
   505            {
       
   506            *iInternalAddress = aInternalAddress;
       
   507            }
       
   508        
       
   509        // Completion is postponed, if IPsec SAs have not yet been updated.
       
   510        if (iActivated ||
       
   511            aStatus != KErrNone)
       
   512            {           
       
   513            DoCompleteNegotiateWithHost(aStatus);
       
   514            }
       
   515        }
       
   516    else if (aStatus == KErrNone)
       
   517        {
       
   518        //This is not the first IKE SA in this session.
       
   519        //If IA has changed we notify the possible address change
       
   520        if(!aInternalAddress.iVPNIfAddr.IsUnspecified())
       
   521            {
       
   522            VirtualIpChanged(aInternalAddress);
       
   523            }
       
   524        }
       
   525    else if(iClientStatusNotifyError != NULL)
       
   526        {
       
   527        //Ike sa establishmet has failed.
       
   528        DoCompleteNotifyError(aStatus);
       
   529        }
       
   530 }
       
   531 
       
   532 
       
   533 void CIkev2PluginSession::VirtualIpChanged(TVPNAddress& aVirtualIp)
       
   534     {    
       
   535     if (iClientStatusInternalAddressChange != NULL)
       
   536         {
       
   537         __ASSERT_DEBUG(iChangedInternalAddress != NULL, User::Invariant());
       
   538         *iChangedInternalAddress = aVirtualIp;
       
   539         User::RequestComplete(iClientStatusInternalAddressChange, KErrNone);
       
   540         iChangedInternalAddress = NULL;
       
   541         }
       
   542     }
       
   543 
       
   544 void CIkev2PluginSession::StartResponding()
       
   545     { 
       
   546     iCurrIkeSaRespCount++; 
       
   547     }
       
   548 
       
   549 
       
   550 void CIkev2PluginSession::StopResponding() 
       
   551     { 
       
   552     if (iCurrIkeSaRespCount)
       
   553         {
       
   554         iCurrIkeSaRespCount--; 
       
   555         }
       
   556     }
       
   557 
       
   558 
       
   559 void CIkev2PluginSession::DeleteIpsecSAData(TUint32 aSAId, const TDesC8& aSpi, TBool aInbound)
       
   560     {
       
   561     __ASSERT_DEBUG(aSpi.Length() == 4, User::Invariant());
       
   562     _LIT8(KZeroSpi, "");
       
   563     CIkev2SA* Ikev2SA = FindIkev2SA(aSAId, KSaStateNotDefined, KSaStateNotDefined);
       
   564     if ( Ikev2SA )
       
   565         {
       
   566         if ( aInbound ) 
       
   567              Ikev2SA->DeleteIpsecSaData(aSpi, KZeroSpi);   
       
   568         else Ikev2SA->DeleteIpsecSaData(KZeroSpi, aSpi);   
       
   569         }   
       
   570     }
       
   571 
       
   572 void CIkev2PluginSession::IkeSaDeleted(TInt aStatus)
       
   573     {
       
   574     if (iClientStatusDelete != NULL)
       
   575         {
       
   576         DoCompleteDeleteSession(aStatus);           
       
   577         }
       
   578     else if (aStatus != KErrNone && iClientStatusNotifyError != NULL)
       
   579         {
       
   580         DoCompleteNotifyError(aStatus);
       
   581         }
       
   582     else if (aStatus != KErrNone && iClientStatusNegotiate != NULL)
       
   583         {
       
   584         TVPNAddress dummyVirtualIp;
       
   585         IkeSaCompleted(aStatus,dummyVirtualIp);        
       
   586         }
       
   587     }
       
   588 
       
   589 
       
   590 CIpsecSaSpecList* CIkev2PluginSession::GetIPsecSaSpecListL( const TInetAddr& aLocalAddr, const TInetAddr& aLocalMask, 
       
   591                                                              const TInetAddr& aRemoteAddr, const TInetAddr& aRemoteMask,
       
   592                                                              TInt aProtocol )
       
   593     {
       
   594     CIpsecSaSpecList* saSpecList = iIpsecPolicyUtil.GetIpseSaSpecListLC( aLocalAddr, aLocalMask, 
       
   595                                                                           aRemoteAddr, aRemoteMask,
       
   596                                                                           aProtocol, iVpnNetId );
       
   597     CleanupStack::Pop(saSpecList);
       
   598     
       
   599     return saSpecList;
       
   600     }
       
   601 
       
   602 
       
   603 TBool CIkev2PluginSession::InheritIpsecSas(TUint32 aDstSAId, TUint32 aSrcSAId)
       
   604     {
       
   605     CIkev2SA* DstIkev2SA = FindIkev2SA(aDstSAId, KSaStateNotDefined, KSaStateNotDefined);
       
   606     if ( DstIkev2SA )
       
   607         {
       
   608         CIkev2SA* SrcIkev2SA = FindIkev2SA(aSrcSAId, KSaStateNotDefined, KSaStateNotDefined);
       
   609         if ( SrcIkev2SA )
       
   610             {   
       
   611             DstIkev2SA->SetIpsecSaQue(SrcIkev2SA->GetIpsecSaQue());
       
   612             return ETrue;
       
   613             }   
       
   614         }   
       
   615     return EFalse;
       
   616     }   
       
   617 
       
   618 
       
   619 TUint32 CIkev2PluginSession::VpnInterfaceIndex() const
       
   620     {
       
   621     return iVpnInterfaceIndex;
       
   622     }
       
   623 
       
   624 TBool CIkev2PluginSession::RemoteAddrChanged(TIkev2SAData* aIkev2SAData, TInetAddr& aNewIp)
       
   625     {
       
   626     __ASSERT_DEBUG(aIkev2SAData, User::Invariant());
       
   627     CIkev2SA* Ikev2SA = FindIkev2SA(aIkev2SAData->SaId(), KSaStateNotDefined, KSaStateNotDefined);
       
   628     if ( Ikev2SA )
       
   629          return Ikev2SA->RemoteAddrChanged(aNewIp);
       
   630     else return ETrue;
       
   631     }
       
   632 
       
   633 void CIkev2PluginSession::KeepAliveIkeSAL(TIkev2SAData* aIkev2SAdata)
       
   634     {
       
   635     ASSERT(aIkev2SAdata);
       
   636     CIkev2Negotiation* Negotiation = FindNegotiation(aIkev2SAdata->SaId(), KSaStateNotDefined);
       
   637     if ( Negotiation )
       
   638         {
       
   639         //There is already some negotiation going on this SA, don't send keep-alive
       
   640         return; 
       
   641         }        
       
   642     
       
   643     Negotiation = CIkev2Negotiation::NewL(*this, iPfKeySocketIf, 
       
   644                                           iEventLogger, *iMessageSendQue, 
       
   645                                           iDebug, *aIkev2SAdata);
       
   646     CleanupStack::PushL(Negotiation);
       
   647     Negotiation->SendKeepAliveMsgL();
       
   648     if ( Negotiation->Stopped() )
       
   649         {
       
   650         CleanupStack::PopAndDestroy(Negotiation);
       
   651         }
       
   652     else
       
   653         {
       
   654         CleanupStack::Pop(Negotiation);
       
   655         }
       
   656     }
       
   657 
       
   658 CIkev2Negotiation* CIkev2PluginSession::FindNegotiation(TUint32 aSAId, TInt aRequiredState)
       
   659     {
       
   660         //
       
   661         // Find IKEv2 negotiation object using SAId as search argument 
       
   662         //
       
   663         CIkev2Negotiation* Neg = iFirstNegotiation;
       
   664         while ( Neg )
       
   665         {
       
   666             if ( ( Neg->iHdr.SaId() == aSAId )
       
   667                    &&
       
   668                  ( ( aRequiredState == KSaStateNotDefined) ||
       
   669                    ( aRequiredState == Neg->iHdr.iSAState ) ) )
       
   670             {   
       
   671                 break;
       
   672             }   
       
   673             
       
   674             Neg = Neg->iNext;
       
   675         }   
       
   676         return Neg;     
       
   677     }
       
   678 
       
   679 TBool CIkev2PluginSession::DeleteIkeSAL(TIkev2SAData* aIkev2SAdata, TBool aNormal)
       
   680     {
       
   681     ASSERT(aIkev2SAdata);
       
   682     //
       
   683     // An IKE SA delete request received
       
   684     // Check first does there exists an ongoing negotiation on this IKE
       
   685     // SA deleted and delete this block. 
       
   686     // Allocate a new negotiation with TIkev2SAData and initiate IKE SA
       
   687     // deletion request
       
   688     //
       
   689         DEBUG_LOG1(_L("Deleting IKE SA SAID =  %d"), aIkev2SAdata->SaId());
       
   690                 
       
   691         CIkev2Negotiation* Negotiation = FindNegotiation(aIkev2SAdata->SaId(), KSaStateNotDefined);
       
   692         while ( Negotiation )
       
   693         {
       
   694             delete Negotiation; // destructor removes object from queue, too
       
   695             Negotiation = FindNegotiation(aIkev2SAdata->SaId(), KSaStateNotDefined);            
       
   696         }
       
   697 
       
   698         TBool Started = EFalse;
       
   699         if ( aNormal )
       
   700         {   
       
   701            Negotiation = CIkev2Negotiation::NewL(*this, iPfKeySocketIf, 
       
   702                                                  iEventLogger, *iMessageSendQue, 
       
   703                                                  iDebug, *aIkev2SAdata);
       
   704            CleanupStack::PushL(Negotiation);
       
   705            Negotiation->StartIkeSADeleteL();
       
   706            CleanupStack::Pop(Negotiation);
       
   707            if ( Negotiation->Stopped() )
       
   708                 delete Negotiation;
       
   709            else Started = ETrue;   
       
   710         }
       
   711         else
       
   712         {
       
   713           DEBUG_LOG(_L("Forced close, no delete payload(s) sent"));
       
   714         }
       
   715                 
       
   716         DeleteIkev2SA(aIkev2SAdata->SaId());
       
   717 
       
   718         return Started;
       
   719     }
       
   720 
       
   721 void CIkev2PluginSession::RekeyIkeSAL(TIkev2SAData* aIkev2SAdata)
       
   722     {
       
   723     ASSERT(aIkev2SAdata);
       
   724       //
       
   725       // Rekey specified IKE SA
       
   726       //
       
   727         DEBUG_LOG1(_L("Starting to rekey IKE SA SAID =  %d"), aIkev2SAdata->SaId());
       
   728         CIkev2Negotiation* Negotiation = CIkev2Negotiation::NewL(*this, iPfKeySocketIf, 
       
   729                                                                  iEventLogger, *iMessageSendQue, 
       
   730                                                                  iDebug, *aIkev2SAdata);
       
   731         CleanupStack::PushL(Negotiation);
       
   732         Negotiation->BuildIkeSaRekeyMsgL(ETrue);        
       
   733         if ( Negotiation->Stopped() )
       
   734              CleanupStack::PopAndDestroy(Negotiation);
       
   735         else CleanupStack::Pop(Negotiation);
       
   736     }
       
   737 
       
   738 void CIkev2PluginSession::IkeMsgReceived( const ThdrISAKMP& aIkeMsg,
       
   739                                           const TInetAddr& aSrcAddr,
       
   740                                           TInt aLocalPort)
       
   741     {       
       
   742       TRAPD(err, IkeMessageReceivedL(aIkeMsg, aSrcAddr, aLocalPort));
       
   743       if (err != KErrNone)
       
   744         {
       
   745         //Leave that we have not been able to handle
       
   746         //above layers. We close the connection and report an error.
       
   747         IkeSaDeleted(err);
       
   748         }
       
   749     }
       
   750 
       
   751 // ---------------------------------------------------------------------------
       
   752 // From class MIkev2ReceiverCallback
       
   753 // Handles notification about receive error. 
       
   754 // ---------------------------------------------------------------------------
       
   755 //
       
   756 void CIkev2PluginSession::ReceiveError( TInt aError )
       
   757     {
       
   758     IkeSaDeleted( aError );
       
   759     }
       
   760 
       
   761 void CIkev2PluginSession::IkeMessageReceivedL(const ThdrISAKMP& aIkeMessage, 
       
   762                                               const TInetAddr &aRemote, 
       
   763                                               TUint16 aLocalPort)
       
   764 	{
       
   765 	
       
   766 		//
       
   767 		// Do sanity check Parse incoming IKE message 
       
   768 		//
       
   769 		TUint32 NegotiationId;
       
   770 		if ( !CheckIkeMessageHeader(aIkeMessage, NegotiationId) )
       
   771 			return; // Format error in received IKE message header
       
   772 
       
   773 		TBool CleanUpUsed = EFalse;
       
   774 		CIkev2Negotiation* Negotiation;		
       
   775 		if ( NegotiationId )
       
   776 		{
       
   777 		   //
       
   778 		   // Try to find ongoing IKEv2 negotiation with Id
       
   779 		   //
       
   780 		   Negotiation = FindNegotiation(NegotiationId, KSaStateNotDefined);
       
   781 		   if ( !Negotiation )
       
   782 		   {
       
   783                if (!(aIkeMessage.GetFlags() & IKEV2_RESPONSE_MSG))
       
   784                {
       
   785                   //
       
   786                   // Try to find an IKEv2 SA with negotiation ID
       
   787                   //
       
   788                   TIkev2SAData* Ikev2SAdata = FindIkev2SAData(NegotiationId,
       
   789                                                               KSaStateNotDefined, KSaStateNotDefined);
       
   790                   if ( Ikev2SAdata )
       
   791                   {
       
   792                      Negotiation = CIkev2Negotiation::NewL(*this, iPfKeySocketIf, 
       
   793                                                            iEventLogger, *iMessageSendQue, 
       
   794                                                            iDebug, *Ikev2SAdata);
       
   795                      CleanupStack::PushL(Negotiation);
       
   796                      CleanUpUsed = ETrue;
       
   797                   }
       
   798                   else
       
   799                   {								  
       
   800                      DEBUG_LOG(_L("Receive IKE message cannot be associated"));					 
       
   801                      return;			 
       
   802                   }
       
   803                }
       
   804                else
       
   805                {
       
   806                    DEBUG_LOG(_L("Received response message, but we don't have associated negotiation"));
       
   807                    DEBUG_LOG(_L("--> Message silently discarded."));
       
   808                    return;
       
   809                }
       
   810 		   }	   
       
   811 		}
       
   812 		else
       
   813 		{
       
   814 		   //
       
   815 		   // Negotiation ID has zero value. This must be an IKE_SA_INIT
       
   816 		   // message from peer where Responder SPI has zero value
       
   817 		   // Get a new negotiation object
       
   818 		   //
       
   819 		   
       
   820 		   TInetAddr localAddr;
       
   821 		   iDataInterface.GetLocalAddress(localAddr);
       
   822 		   Negotiation = CIkev2Negotiation::NewL(*this, iPfKeySocketIf, iEventLogger, 
       
   823 		                                         *iMessageSendQue, iDebug,
       
   824                                                  iIkeData, iVpnIapId, this->GetSAId(), 
       
   825                                                  localAddr,
       
   826                                                  aRemote);
       
   827 		   CleanupStack::PushL(Negotiation);
       
   828 		   if ( !Negotiation->StartRespondingL(aIkeMessage) )
       
   829 		   {
       
   830 			  if ( Negotiation->Stopped() )
       
   831 				   CleanupStack::PopAndDestroy(Negotiation);
       
   832 			  else CleanupStack::Pop(Negotiation);
       
   833 			  return;
       
   834 		   }	   
       
   835 		   CleanUpUsed = ETrue;
       
   836 		}
       
   837 		   
       
   838 		Negotiation->ProcessIkeMessageL(aIkeMessage, (TInetAddr&)aRemote, aLocalPort);
       
   839 		if ( CleanUpUsed )
       
   840 		    CleanupStack::Pop(Negotiation);
       
   841 		
       
   842 		if ( Negotiation->Stopped() )
       
   843 			delete Negotiation;
       
   844 	}
       
   845 
       
   846 TBool CIkev2PluginSession::CheckIkeMessageHeader(const ThdrISAKMP& aIkeMessage, TUint32& NegotiationId)
       
   847     {
       
   848         //
       
   849         // Do the following sanity checks to incoming IKE message fixed
       
   850         // header
       
   851         // -- Check that Exchange type has some value specified in IKEv2
       
   852         // -- Check that Next Payload has some value specified in IKEv2
       
   853         // -- Check that Inititor SPI has not "zero" value
       
   854         //              
       
   855        TUint8 ExchangeType = aIkeMessage.GetExchange();
       
   856        if ( (ExchangeType < IKE_SA_INIT) || (ExchangeType > INFORMATIONAL) )
       
   857        {
       
   858           DEBUG_LOG1(_L("Unsupported Exchange Type: %d"),ExchangeType);
       
   859           return EFalse;                  
       
   860        }
       
   861        
       
   862        TUint32 SPI_I_Low       =  aIkeMessage.GetSPI_I_Low32();
       
   863        TUint32 NegotiationId_I = aIkeMessage.GetNegotiationID_I();
       
   864        if ( (SPI_I_Low == 0 ) && ( NegotiationId_I == 0 ) )
       
   865        {
       
   866            DEBUG_LOG(_L("Initiator SPI has zero value !\n"));  
       
   867            return EFalse;                 
       
   868        }
       
   869         //
       
   870         // The negotiation id is a 32-bit (not zero) id value which
       
   871         // unambiguously identiefies an IKEv2 negotiation object (CIkev2Negotiation).
       
   872         // This negotiation id is packed into the SPI value ( 32 most
       
   873         // significant bits of SPI) defined by the local end (=us).
       
   874         // Get the negotiation id from local SPI in IKE message
       
   875         // according to Initiator Bit in received IKE message header
       
   876         // flags.
       
   877         // Initiator = 1 ==> Get negotiation id from responder SPI
       
   878         // Initiator = 0 ==> Get negotiation id from initiator SPI
       
   879         //
       
   880        aIkeMessage.GetFlags();
       
   881        if ( aIkeMessage.GetFlags() & IKEV2_INITIATOR )
       
   882             NegotiationId = aIkeMessage.GetNegotiationID_R();
       
   883        else NegotiationId = NegotiationId_I;                   
       
   884 
       
   885        return ETrue;
       
   886     }
       
   887 
       
   888 
       
   889 void CIkev2PluginSession::DeleteIpsecSA( const TUint32 aSPI, const TInetAddr& aSrc,
       
   890                                   const TInetAddr& aDst, const TUint8 aProtocol )
       
   891     {
       
   892     iPfKeySocketIf.DeleteSA(aSPI, aSrc, aDst, aProtocol); 
       
   893     }
       
   894 
       
   895 
       
   896 void CIkev2PluginSession::AddSAL( const TIpsecSAData& aSAData )    
       
   897     {
       
   898     iPfKeySocketIf.AddSAL( aSAData );
       
   899     }
       
   900 
       
   901 
       
   902 void CIkev2PluginSession::UpdateSAL( const TIpsecSAData& aSAData )
       
   903     {
       
   904     iPfKeySocketIf.UpdateSAL( aSAData );
       
   905     }
       
   906 
       
   907 
       
   908 TIkev2SAData* CIkev2PluginSession::FindIkev2SAData(TUint32 aSAId, TInt aRequiredState, TInt aNewState)
       
   909     {
       
   910     TIkev2SAData* SaData = NULL;        
       
   911     CIkev2SA* Ikev2SA = FindIkev2SA(aSAId, aRequiredState, aNewState);
       
   912     if ( Ikev2SA )
       
   913         SaData = (TIkev2SAData*)&Ikev2SA->iIkeV2SaData; 
       
   914     return SaData;
       
   915     }
       
   916 
       
   917 void CIkev2PluginSession::PfkeyMessageReceived(const TPfkeyMessage& aPfkeyMessage)
       
   918     {
       
   919     TRAPD(err, PfkeyMessageReceivedL(aPfkeyMessage));
       
   920     if (err != KErrNone)
       
   921         {
       
   922         //Leave that we have not been able to handle
       
   923         //above layers. We close the connection and report an error.
       
   924         IkeSaDeleted(err);   
       
   925         }
       
   926     }
       
   927 
       
   928 void CIkev2PluginSession::PfkeyMessageReceivedL(const TPfkeyMessage& aPfkeyMessage)
       
   929     {
       
   930         //
       
   931         //  Process received PFKEY message according to message type
       
   932         //                 
       
   933         TIkev2SAData* Ikev2SAdata = NULL;
       
   934         CIkev2Negotiation* Negotiation = NULL;     
       
   935         TBool CleanUpUsed = EFalse;
       
   936         
       
   937         __ASSERT_DEBUG(aPfkeyMessage.iBase.iMsg->sadb_msg_type != SADB_GETSPI, User::Invariant());
       
   938         switch ( aPfkeyMessage.iBase.iMsg->sadb_msg_type )
       
   939         {            
       
   940             case SADB_ADD:
       
   941                 {
       
   942                 if ( !iActivated )
       
   943                     {
       
   944                     DEBUG_LOG(_L("Updating of IPsec SAs completed"));
       
   945                     iActivated = ETrue;
       
   946                     TVPNAddress dummyVirtualIp;
       
   947                     IkeSaCompleted(KErrNone,dummyVirtualIp);
       
   948                     }
       
   949                 break;
       
   950             case SADB_ACQUIRE:
       
   951             if ( iClientStatusDelete != NULL )
       
   952                 {
       
   953                 DEBUG_LOG(_L("Acquire ignored because of ongoing deactivation."));
       
   954                 return;                    
       
   955                 }
       
   956                 if (iFirstIkev2SA != NULL)
       
   957                     {
       
   958                     Ikev2SAdata = &(iFirstIkev2SA->iIkeV2SaData);
       
   959                     }
       
   960                  if ( Ikev2SAdata )
       
   961                  {
       
   962                     DEBUG_LOG(_L("Found IKE SA for the acquire"));
       
   963                     //
       
   964                     // An IKE SA found for Acquire. Get a negotiation
       
   965                     // object for IKE Child SA exchange 
       
   966                     //
       
   967                      Negotiation = CIkev2Negotiation::NewL(*this, iPfKeySocketIf,
       
   968                                                            iEventLogger, *iMessageSendQue, 
       
   969                                                            iDebug,*Ikev2SAdata);
       
   970                      CleanupStack::PushL(Negotiation);
       
   971                      CleanUpUsed = ETrue;
       
   972                  }
       
   973                  else
       
   974                  {
       
   975                      DEBUG_LOG(_L("No IKE SA for the Acquire. Creating new."));
       
   976                     //
       
   977                     // No IKE SA found for Acquire not ongoing
       
   978                     // negotiation found for defined destination
       
   979                     // address.
       
   980                     // We shall start a new IKE SA negotiation to
       
   981                     // defined destination address. Find first the IKE
       
   982                     // policy for that destination address.
       
   983                     //
       
   984                     TInetAddr localAddr;
       
   985                     this->iDataInterface.GetLocalAddress(localAddr);                     
       
   986                      Negotiation = CIkev2Negotiation::NewL(*this, iPfKeySocketIf, iEventLogger, 
       
   987                                                            *iMessageSendQue, iDebug, iIkeData, 
       
   988                                                            iVpnIapId, GetSAId(),
       
   989                                                            localAddr,
       
   990                                                            *(aPfkeyMessage.iDstAddr.iAddr));
       
   991                      CleanupStack::PushL(Negotiation);
       
   992                      CleanUpUsed = ETrue;
       
   993                  }
       
   994                  Negotiation->ProcessAcquireL(aPfkeyMessage);
       
   995                  if ( CleanUpUsed )
       
   996                     CleanupStack::Pop(Negotiation);
       
   997                  if ( Negotiation->Stopped() )
       
   998                     delete Negotiation;
       
   999                  break;
       
  1000 
       
  1001             case SADB_EXPIRE:                  
       
  1002                   if (aPfkeyMessage.iSoft.iExt)
       
  1003                     {
       
  1004                     //
       
  1005                     // An IPSEC SA soft lifetime has expired.
       
  1006                     //
       
  1007                     // Try to find an existing IKE SA with remote address 
       
  1008                     //
       
  1009                     if (iFirstIkev2SA != NULL)
       
  1010                         {
       
  1011                         Ikev2SAdata = &(iFirstIkev2SA->iIkeV2SaData);
       
  1012                         }
       
  1013                     if ( Ikev2SAdata )
       
  1014                         {
       
  1015                         //
       
  1016                         // An IKE SA found for soft expire. Get a negotiation
       
  1017                         // object for IKE Child SA exchange 
       
  1018                         //
       
  1019                         Negotiation = CIkev2Negotiation::NewL(*this, iPfKeySocketIf, iEventLogger, 
       
  1020                                                               *iMessageSendQue, iDebug, *Ikev2SAdata);
       
  1021                         CleanupStack::PushL(Negotiation);
       
  1022                         DEBUG_LOG(_L("IKE SA found for soft expire IP."));
       
  1023                         
       
  1024                         Negotiation->StartIpsecSaRekeyingL(aPfkeyMessage);
       
  1025                         CleanupStack::Pop(Negotiation);
       
  1026                         if ( Negotiation->Stopped() )
       
  1027                             delete Negotiation;
       
  1028                         }
       
  1029                     else
       
  1030                         {
       
  1031                         DEBUG_LOG(_L("No IKE SA found for soft expire IP"));
       
  1032                         }                                      
       
  1033                     }
       
  1034                   else
       
  1035                     {
       
  1036                     //
       
  1037                     // An IPSEC SA has been expired.
       
  1038                     // Try to find an existing IKE SA with remote address 
       
  1039                     //
       
  1040                     if (iFirstIkev2SA != NULL)
       
  1041                         {
       
  1042                         Ikev2SAdata = &(iFirstIkev2SA->iIkeV2SaData);
       
  1043                         }
       
  1044                     if ( Ikev2SAdata )
       
  1045                         {
       
  1046                         //
       
  1047                         // An IKE SA found for Expire. Get a negotiation
       
  1048                         // object for IKE Informational exchange 
       
  1049                         //
       
  1050                         Negotiation = CIkev2Negotiation::NewL(*this, iPfKeySocketIf, iEventLogger, 
       
  1051                                                               *iMessageSendQue, iDebug, *Ikev2SAdata);
       
  1052                         CleanupStack::PushL(Negotiation);
       
  1053                         DEBUG_LOG(_L("IKE SA found for Expire IP"));
       
  1054                         
       
  1055                         Negotiation->ProcessExpireL(aPfkeyMessage);
       
  1056                         CleanupStack::Pop(Negotiation);
       
  1057                         if ( Negotiation->Stopped() )
       
  1058                             delete Negotiation;                     
       
  1059                         }
       
  1060                     else
       
  1061                         {
       
  1062                         DEBUG_LOG(_L("No IKE SA found Expire IP"));                            
       
  1063                         }                        
       
  1064                     }                   
       
  1065                   break;  
       
  1066                 }
       
  1067             default:
       
  1068                  break;
       
  1069         }
       
  1070     }
       
  1071 
       
  1072 TBool CIkev2PluginSession::MatchDestinationAddress( const TInetAddr& aDestAddr ) const
       
  1073     {
       
  1074     TBool match( EFalse );
       
  1075     
       
  1076     if ( iIkeData )
       
  1077         {
       
  1078         match = iIkeData->iAddr.Match( aDestAddr );
       
  1079         }    
       
  1080     return match;
       
  1081     }
       
  1082 
       
  1083 void CIkev2PluginSession::DeactivationTimeout()
       
  1084     {
       
  1085     IkeSaDeleted(KErrTimedOut);
       
  1086     }
       
  1087 
       
  1088 // ---------------------------------------------------------------------------
       
  1089 // Handles completion of client's negotiate request.
       
  1090 // ---------------------------------------------------------------------------
       
  1091 //
       
  1092 void CIkev2PluginSession::DoCompleteNegotiateWithHost( TInt aStatus )
       
  1093     {    
       
  1094     if ( aStatus != KErrNone )
       
  1095         {
       
  1096         DoCancelActiveOperations();       
       
  1097         }
       
  1098     else
       
  1099         {
       
  1100         iActivated = ETrue;       
       
  1101         }
       
  1102     
       
  1103     User::RequestComplete( iClientStatusNegotiate, aStatus );
       
  1104     }
       
  1105 
       
  1106 // ---------------------------------------------------------------------------
       
  1107 // Handles completion of client's delete session request.
       
  1108 // ---------------------------------------------------------------------------
       
  1109 //
       
  1110 void CIkev2PluginSession::DoCompleteDeleteSession( TInt aStatus )
       
  1111     {       
       
  1112     delete iIkeData;
       
  1113     iIkeData = NULL;
       
  1114     delete iDeactivationTimer;
       
  1115     iDeactivationTimer = NULL;
       
  1116     
       
  1117     if ( aStatus != KErrCancel )
       
  1118         {
       
  1119         DoCancelActiveOperations();
       
  1120         }
       
  1121     User::RequestComplete( iClientStatusDelete, aStatus );
       
  1122     }
       
  1123 
       
  1124 // ---------------------------------------------------------------------------
       
  1125 // Handles completion of client's notify error request.
       
  1126 // ---------------------------------------------------------------------------
       
  1127 //
       
  1128 void CIkev2PluginSession::DoCompleteNotifyError( TInt aStatus )
       
  1129     {
       
  1130     if ( aStatus != KErrCancel )
       
  1131         {
       
  1132         DoCancelActiveOperations();
       
  1133         }
       
  1134     User::RequestComplete( iClientStatusNotifyError, aStatus );    
       
  1135     }
       
  1136 
       
  1137 // ---------------------------------------------------------------------------
       
  1138 // Cancels active operations.
       
  1139 // ---------------------------------------------------------------------------
       
  1140 //
       
  1141 void CIkev2PluginSession::DoCancelActiveOperations()
       
  1142     {
       
  1143     // Cancel active negotiation operations.
       
  1144     CIkev2Negotiation* negotiation = iFirstNegotiation;
       
  1145     while ( negotiation != NULL )
       
  1146         {
       
  1147         negotiation->CancelOperation();
       
  1148         negotiation = negotiation->iNext;
       
  1149         }
       
  1150 
       
  1151     // Cancel active IKE SA operations.
       
  1152     CIkev2SA* ikev2Sa = iFirstIkev2SA;
       
  1153     while( ikev2Sa != NULL )
       
  1154         {
       
  1155         ikev2Sa->Cancel();
       
  1156         ikev2Sa = ikev2Sa->iNext;
       
  1157         }                        
       
  1158     
       
  1159     DoCancelDataTransfer();
       
  1160     }
       
  1161 
       
  1162 // ---------------------------------------------------------------------------
       
  1163 // Cancels data transfer.
       
  1164 // ---------------------------------------------------------------------------
       
  1165 //
       
  1166 void CIkev2PluginSession::DoCancelDataTransfer()
       
  1167     {
       
  1168     if ( iReceiver != NULL )
       
  1169         {
       
  1170         iReceiver->StopReceive();
       
  1171         }
       
  1172     if ( iMessageSendQue != NULL )
       
  1173         {
       
  1174         iMessageSendQue->Cancel();
       
  1175         iMessageSendQue->CancelAll();
       
  1176         }        
       
  1177     }