vpnengine/ikev2lib/src/ikev2sa.cpp
changeset 0 33413c0669b9
child 10 68dc8923de26
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 2003-2007 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:  IKEv2 SA
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "ikedebug.h"
       
    20 #include "ikev2SA.h"
       
    21 #include "ikepolparser.h"
       
    22 #include "ikev2ipsecsadata.h"
       
    23 #include "ikev2pluginsession.h"
       
    24 
       
    25 CIkev2SA* CIkev2SA::NewL(CIkev2PluginSession& aIkeV2PluginSession, TIkev2SAData& aIkev2SAdata, MIkeDebug& aDebug)
       
    26 {
       
    27 	CIkev2SA *sa = new (ELeave) CIkev2SA(aIkeV2PluginSession, aDebug);
       
    28 	sa->ConstructL(aIkev2SAdata);
       
    29 	return sa;
       
    30 }
       
    31 
       
    32 
       
    33 CIkev2SA::CIkev2SA(CIkev2PluginSession& aIkeV2PluginSession, MIkeDebug& aDebug)
       
    34 :CTimer(EPriorityStandard), iIkeV2PluginSession(aIkeV2PluginSession), iDebug(aDebug)
       
    35 {
       
    36     CActiveScheduler::Add(this);
       
    37 }
       
    38 
       
    39 
       
    40 void CIkev2SA::ConstructL(TIkev2SAData& aIkev2SAdata)
       
    41 {
       
    42 	CTimer::ConstructL();		
       
    43 	iIkeV2SaData.Copy(aIkev2SAdata);
       
    44 	//
       
    45 	// Calculate lifetime value for the new IKE SA
       
    46 	// The jitter value is adjusted from SA internal ID (SAId mod 8) 
       
    47 	//
       
    48     iRemainingTime = iIkeV2SaData.iLifetime + (iIkeV2SaData.SaId() % 8);
       
    49 	iIkeV2SaData.iSAState  = KSaStateReady;
       
    50 
       
    51 	TInt DPDHeartbeat = 0;
       
    52 	if ( iIkeV2SaData.iIkeData->iDPDHeartBeat )
       
    53 	   DPDHeartbeat = iIkeV2SaData.iIkeData->iDPDHeartBeat;      
       
    54 
       
    55 	if ( DPDHeartbeat )
       
    56 	{
       
    57 		iIkeKeepAlive = CIkeV2KeepAlive::NewL(DPDHeartbeat, *this);
       
    58 	}
       
    59 										  
       
    60 	DEBUG_LOG2(_L("IKEv2 SA constructed, SAId: %d, Lifetime: %d"), iIkeV2SaData.SaId(), iRemainingTime);
       
    61 	
       
    62 	StartTimer();
       
    63 }
       
    64 
       
    65 
       
    66 CIkev2SA::~CIkev2SA()
       
    67 {
       
    68     if (IsActive())
       
    69         Cancel();
       
    70 	PurgeIpsecDataQue();  	
       
    71 	iIkeV2SaData.CleanUp();
       
    72 	delete iIkeKeepAlive;	
       
    73 }
       
    74 
       
    75 
       
    76 void CIkev2SA::DoCancel()
       
    77 {
       
    78     CTimer::DoCancel();
       
    79 }
       
    80 
       
    81 void CIkev2SA::UpdateL(TIkev2SAData* aIkev2SAdata, TIkeV2IpsecSAData* aIpsecSAdata)
       
    82 {
       
    83     DEBUG_LOG(_L("CIkev2SA::UpdateL"));
       
    84 
       
    85 	if ( aIkev2SAdata )
       
    86 	{
       
    87 	   //
       
    88 	   // Update IKE Sa data information and reset/restart IKE SA lifetime
       
    89 	   //
       
    90 	    iIkeV2SaData.Copy(*aIkev2SAdata);
       
    91 	    iIkeV2SaData.iSAState = KSaStateReady;		
       
    92 	}
       
    93 	if ( aIpsecSAdata )
       
    94 	{
       
    95 	   //
       
    96 	   // Link an Ipsec SA pair information into IKE SA
       
    97 	   //
       
    98 		TIkeV2IpsecSAData* IpsecSA = new (ELeave) TIkeV2IpsecSAData(iDebug);
       
    99 		IpsecSA->Copy(*aIpsecSAdata);
       
   100 		LinkIpsecSa(IpsecSA);						  
       
   101 		DEBUG_LOG3(_L("Ipsec SA added into IKE SA, SAId: %d, In SPI: %d, Out SPI: %d"),
       
   102 				   iIkeV2SaData.SaId(), &aIpsecSAdata->iSPI_In, &aIpsecSAdata->iSPI_Out);
       
   103 	}
       
   104 }
       
   105 
       
   106 TBool CIkev2SA::RemoteAddrChanged(TInetAddr& aNewIp)
       
   107 {
       
   108 
       
   109 #if __DEBUG
       
   110 	TBuf<40> txt_addr;				
       
   111 	aNewIp.OutputWithScope(txt_addr);
       
   112 	DEBUG_LOG2(_L("Remote IP changed IKE SA: %d, new address %S"), iIkeV2SaData.SaId(), &txt_addr);
       
   113 #endif //__DEBUG
       
   114 	aNewIp = aNewIp; //To silence UREL warnings: contents of DEB macro invisible in UREL builds
       
   115 	
       
   116 	return ETrue;
       
   117 }
       
   118 
       
   119 
       
   120 TIkeV2IpsecSAData* CIkev2SA::RemoveIpsecSaData(const TDesC8& aInSpi, const TDesC8& aOutSpi)
       
   121 { 
       
   122     return FindIpsecSaData(aInSpi, aOutSpi, ETrue); 
       
   123 } 
       
   124 
       
   125 
       
   126 TIkeV2IpsecSAData* CIkev2SA::FindIpsecSaData(const TDesC8& aInSpi, const TDesC8& aOutSpi, TBool aRemove)
       
   127 {
       
   128 
       
   129     __ASSERT_DEBUG( aInSpi.Length() == 4 || aInSpi.Length() == 0, User::Invariant() );
       
   130     __ASSERT_DEBUG( aOutSpi.Length() == 4 || aOutSpi.Length() == 0, User::Invariant() );
       
   131     __ASSERT_DEBUG( aInSpi.Length() != 0 || aOutSpi.Length() != 0, User::Invariant() );
       
   132 
       
   133 	TInt Found = 0;
       
   134 	if ( aInSpi.Length() > 0 )
       
   135 		Found ++;
       
   136 	if ( aOutSpi.Length() > 0 )
       
   137 		Found ++;
       
   138 	if ( Found == 0 )
       
   139 	   return NULL;	
       
   140 
       
   141 	TInt Match;
       
   142 	TIkeV2IpsecSAData* Prev = NULL;
       
   143 	TIkeV2IpsecSAData* Sa   = iIpsecSaQue;
       
   144 
       
   145 	while ( Sa )
       
   146 	{
       
   147 		Match = 0;
       
   148 		if ( aInSpi.Length() > 0 && (aInSpi.Compare(Sa->iSPI_In) == 0))
       
   149            Match ++;   		
       
   150 		if ( aOutSpi.Length() > 0 && (aOutSpi.Compare(Sa->iSPI_Out) == 0) )
       
   151 		   Match ++;
       
   152 		if ( Match == Found )
       
   153 		{
       
   154 		   if ( aRemove )
       
   155 		   {
       
   156 			  if ( Prev )
       
   157 				   Prev->iNext = Sa->iNext;
       
   158 			  else iIpsecSaQue = Sa->iNext;
       
   159 		   }	   
       
   160 		   break;
       
   161 		}
       
   162 		Prev = Sa;
       
   163 		Sa   = Sa->iNext;
       
   164 	}
       
   165 	return Sa;
       
   166 }
       
   167 
       
   168 void CIkev2SA::DeleteIpsecSaData(const TDesC8& aInSpi, const TDesC8& aOutSpi)
       
   169 {
       
   170 	TIkeV2IpsecSAData* SaData = FindIpsecSaData(aInSpi, aOutSpi, ETrue);
       
   171 	if ( SaData )
       
   172 	{
       
   173 		SaData->PurgeKeyMaterial();
       
   174 		SaData->DeleteRekeyData();
       
   175 		DeleteIpsecSas(SaData);		
       
   176 		delete SaData;
       
   177 	}	
       
   178 }
       
   179 
       
   180 void CIkev2SA::LinkIpsecSa(TIkeV2IpsecSAData* aSa) 
       
   181 {
       
   182     ASSERT(aSa);
       
   183     aSa->iNext = iIpsecSaQue; 
       
   184     iIpsecSaQue = aSa;
       
   185 }   
       
   186 
       
   187 void CIkev2SA::PurgeIpsecDataQue()
       
   188 {
       
   189 	
       
   190 	TIkeV2IpsecSAData* Sa = iIpsecSaQue;
       
   191 	while ( iIpsecSaQue )
       
   192 	{
       
   193 		iIpsecSaQue = Sa->iNext;
       
   194 		Sa->PurgeKeyMaterial();
       
   195 		Sa->DeleteRekeyData();
       
   196 		DeleteIpsecSas(Sa);
       
   197 		delete Sa;
       
   198 		Sa = iIpsecSaQue;
       
   199 	}	
       
   200 }
       
   201 
       
   202 void CIkev2SA::DeleteIpsecSas(TIkeV2IpsecSAData* aSa)
       
   203 {
       
   204     ASSERT(aSa);
       
   205 	TInetAddr LocalAddr;
       
   206 	if ( aSa->iSrcSpecific )
       
   207 		 LocalAddr = iIkeV2SaData.iLocalAddr;
       
   208 	else LocalAddr.Init(0); 
       
   209 	LocalAddr.SetPort(0);	
       
   210 	TInetAddr RemoteAddr = iIkeV2SaData.iRemoteAddr;
       
   211 	RemoteAddr.SetPort(0);
       
   212 	if ( aSa->iSPI_In.Length() > 0 ) 
       
   213 	{
       
   214         TUint32 spi;
       
   215         TPtr8 spiPtr(reinterpret_cast<TUint8*>(&spi), sizeof(spi));
       
   216         spiPtr = aSa->iSPI_In;
       
   217 		iIkeV2PluginSession.DeleteIpsecSA(spi, RemoteAddr, LocalAddr, aSa->iSaType);
       
   218 	}
       
   219 	if ( aSa->iSPI_Out.Length() > 0 )
       
   220 	{
       
   221         TUint32 spi;
       
   222         TPtr8 spiPtr(reinterpret_cast<TUint8*>(&spi), sizeof(spi));
       
   223         spiPtr = aSa->iSPI_Out;
       
   224         iIkeV2PluginSession.DeleteIpsecSA(spi, LocalAddr, RemoteAddr, aSa->iSaType);
       
   225 	}
       
   226 }
       
   227 
       
   228 
       
   229 void CIkev2SA::RunL()
       
   230 {
       
   231 	//
       
   232 	// If IKE SA lifetime expired, delete IKE SA if there is no
       
   233 	// active IPSEC SA:s alive. If there is rekey IKE SA.
       
   234 	//
       
   235     DEBUG_LOG2(_L("CIkev2SA::RunL, SAId=%d, remaining time=%d"),
       
   236             iIkeV2SaData.SaId(), iRemainingTime );
       
   237 	if (iRemainingTime == 0) 
       
   238 	{										 		
       
   239 		if ( iIpsecSaQue )
       
   240 		{
       
   241 		    iIkeV2PluginSession.RekeyIkeSAL(&iIkeV2SaData);
       
   242 		}
       
   243 		else 
       
   244 		{		 
       
   245 		    iIkeV2PluginSession.DeleteIkeSAL(&iIkeV2SaData, ETrue); // "Normal" close
       
   246 		}
       
   247 	}
       
   248 	else StartTimer();
       
   249 	
       
   250 }
       
   251 
       
   252 void CIkev2SA::StartTimer()
       
   253 {
       
   254 	if (iRemainingTime > KMaxTInt/SECOND)   //To avoid overflowing the Timer
       
   255 	{
       
   256 		iRemainingTime -= KMaxTInt/SECOND;
       
   257 		After(KMaxTInt);
       
   258 	}
       
   259 	else    //No overflow
       
   260 	{
       
   261 		After(iRemainingTime*SECOND);
       
   262 		iRemainingTime = 0;
       
   263 	}
       
   264 }
       
   265 
       
   266 
       
   267 void CIkev2SA::EventHandlerL()
       
   268 {
       
   269 	//
       
   270 	// The implementation for class MDpdHeartBeatEventHandler virtual function
       
   271 	// This method is called by an CIkeKeepAlive object instance when
       
   272 	// DPD heartbeat timeout has elapsed.
       
   273 	//
       
   274     iIkeV2PluginSession.KeepAliveIkeSAL(&iIkeV2SaData);
       
   275 }
       
   276 
       
   277 
       
   278 TIkeV2IpsecSAData* CIkev2SA::GetIpsecSaQue()
       
   279 { 
       
   280     TIkeV2IpsecSAData* Que = iIpsecSaQue; 
       
   281     iIpsecSaQue = NULL; 
       
   282     return Que; 
       
   283 }
       
   284 
       
   285 
       
   286 void CIkev2SA::SetIpsecSaQue(TIkeV2IpsecSAData* aQue) 
       
   287 { 
       
   288     if (aQue != NULL) 
       
   289         { 
       
   290         LinkIpsecSa(aQue); 
       
   291         } 
       
   292 }
       
   293