|
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 } |