diff -r 000000000000 -r 33413c0669b9 vpnengine/ikev2lib/src/ikev2messagesendqueue.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikev2lib/src/ikev2messagesendqueue.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,236 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: IKEv2 IKE message send que. +* +*/ + +#include "ikev2messagesendqueue.h" +#include "ikemsgheader.h" +#include "ikedebug.h" + +_LIT8(KKeepaliveData, 0xff); + +CIkev2MessageSendQueue* CIkev2MessageSendQueue::NewL(MIkeDataInterface& aDataInterface, + const TInetAddr& aDestinationAddress, + TUint8 aDscp, + TUint aNatKeepAliveInterval, + MIkeDebug& aDebug) + { + CIkev2MessageSendQueue* self = new (ELeave) CIkev2MessageSendQueue(aDataInterface, + aDestinationAddress, + aDscp, + aNatKeepAliveInterval, + aDebug); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + + return self; + } + + +CIkev2MessageSendQueue::CIkev2MessageSendQueue(MIkeDataInterface& aDataInterface, + const TInetAddr& aDestinationAddress, + TUint8 aDscp, + TUint aNatKeepAliveInterval, + MIkeDebug& aDebug) +:CActive(EPriorityStandard), + iDataInterface(aDataInterface), + iNatKeepAliveInterval(aNatKeepAliveInterval), + iDestinationAddress(aDestinationAddress), + iDscp(aDscp), + iDebug(aDebug) + { + CActiveScheduler::Add(this); + + if (iNatKeepAliveInterval == 0) + { + iNatKeepAliveInterval = 120; + } + } + + +void CIkev2MessageSendQueue::ConstructL() + { + iSender = CIkev2Sender::NewL( iDataInterface, + *this); + User::LeaveIfError(iNatKeepaliveTimer.CreateLocal()); + } + + +CIkev2MessageSendQueue::~CIkev2MessageSendQueue() + { + Cancel(); + iNatKeepaliveTimer.Close(); + iSasBehindNat.Close(); + delete iSender; + iIkeMsgSendBuffer.Reset(); + iIkeMsgSendBuffer.Close(); + } + +void CIkev2MessageSendQueue::SendIkeMessageL(const TPtrC8 aIkeMsg, + TBool aFloatedPort) + { + Cancel(); + if (!iSender->IsActive()) + { + iIkeMsgInSending.Set(aIkeMsg); + TUint port = (aFloatedPort) ? FLOATED_IKE_PORT : IKE_PORT; + +#ifdef _DEBUG + TBuf<80> destAddr; + iDestinationAddress.Output(destAddr); + DEBUG_LOG3(_L("No sending active. Message sent immediately to %S:%d DSCP=%d."), &destAddr, port, iDscp); +#endif //_DEBUG + iDestinationAddress.SetPort(port); + iSender->SendIkeMsg(port, iDestinationAddress, iDscp, iIkeMsgInSending); + } + else + { + DEBUG_LOG(_L("Sending in progress, message added to send queue.")); + TIkeMsgWaitQueueObject waitObject = { aIkeMsg, aFloatedPort }; + User::LeaveIfError(iIkeMsgSendBuffer.Append(waitObject)); + } + } + + +void CIkev2MessageSendQueue::CancelSend(const TPtrC8& aIkeMsg) + { + DEBUG_LOG(_L("Sending of one datagram canceled.")); + if (aIkeMsg.Ptr() == iIkeMsgInSending.Ptr()) + { + __ASSERT_DEBUG(iSender->IsActive(), User::Invariant()); + //The NAT keepalive timer should not be active, because sending + //is in progress. + __ASSERT_DEBUG(!IsActive(), User::Invariant()); + iSender->Cancel(); + iIkeMsgInSending.Set(NULL, 0); + // Send next message from queue. + SendIkeMsgCompleted( KErrCancel ); + } + else + { + for (TUint i = 0; i < iIkeMsgSendBuffer.Count(); ++i) + { + if (iIkeMsgSendBuffer[i].iIkeMsg.Ptr() == aIkeMsg.Ptr()) + { + iIkeMsgSendBuffer.Remove(i); + break; + } + } + } + } + +void CIkev2MessageSendQueue::SendIkeMsgCompleted( TInt /*aStatus*/ ) + { + DEBUG_LOG(_L("Ike message send complete.")); + iIkeMsgInSending.Set(NULL, 0); + + if (iIkeMsgSendBuffer.Count() > 0) + { + TIkeMsgWaitQueueObject& waitObject = iIkeMsgSendBuffer[0]; + TUint port = (waitObject.iFloatedPort) ? FLOATED_IKE_PORT : 500; + iSender->SendIkeMsg(port, iDestinationAddress, iDscp, waitObject.iIkeMsg); + iIkeMsgSendBuffer.Remove(0); + iIkeMsgInSending.Set(waitObject.iIkeMsg); + } + else if (iSasBehindNat.Count() > 0 && iNatKeepAliveInterval > 0) + { + ArmKeepaliveTimer(); + } + } + + +void CIkev2MessageSendQueue::CancelAll() + { + iSender->Cancel(); + iIkeMsgSendBuffer.Reset(); + } + + +void CIkev2MessageSendQueue::NewSaBehindNatL(TUint aSaId) + { + DEBUG_LOG1(_L("CIkev2MessageSendQueue::NewSaBehindNatL: SaId=%d"), aSaId); + __ASSERT_DEBUG(iSasBehindNat.Find(aSaId) == KErrNotFound, User::Invariant()); + User::LeaveIfError(iSasBehindNat.Append(aSaId)); + if (!iSender->IsActive() && iNatKeepAliveInterval > 0) + { + //No sending acticve arm the nat keepalive timer. + ArmKeepaliveTimer(); + } + } + + +void CIkev2MessageSendQueue::SaBehindNatDeleted(TUint aSaId) + { + DEBUG_LOG1(_L("CIkev2MessageSendQueue::SaBehindNatDeleted: SaId=%d"), aSaId); + TInt index = iSasBehindNat.Find(aSaId); + __ASSERT_DEBUG(index >= 0, User::Invariant()); + iSasBehindNat.Remove(index); + if (iSasBehindNat.Count() == 0) + { + //Cancel keepalive timer + Cancel(); + } + } + +void CIkev2MessageSendQueue::RunL() + { + //Send the NAT keepalive + + __ASSERT_DEBUG(!iSender->IsActive(), User::Invariant()); + __ASSERT_DEBUG(iSasBehindNat.Count() > 0 && iNatKeepAliveInterval > 0, User::Invariant()); + + if (iRemainingTime == 0) + { + DEBUG_LOG(_L("Sending NAT keepalive")); + iSender->SendIkeMsg(FLOATED_IKE_PORT, iDestinationAddress, iDscp, KKeepaliveData); + } + else if (iRemainingTime > KMaxTInt/1000000) + { + iRemainingTime -= KMaxTInt/1000000; + iNatKeepaliveTimer.After(iStatus, KMaxTInt); + SetActive(); + } + else + { + iNatKeepaliveTimer.After(iStatus, iRemainingTime*1000000); + iRemainingTime = 0; + SetActive(); + } + } + +void CIkev2MessageSendQueue::DoCancel() + { + iNatKeepaliveTimer.Cancel(); + iRemainingTime = 0; + DEBUG_LOG(_L("Keepalive timer canceled")); + } + +void CIkev2MessageSendQueue::ArmKeepaliveTimer() + { + DEBUG_LOG(_L("CIkev2MessageSendQueue::ArmKeepaliveTimer")); + //Arm NAT keepalive timer. + if (iNatKeepAliveInterval > KMaxTInt/1000000 ) + { + iRemainingTime = iNatKeepAliveInterval - KMaxTInt/1000000; + iNatKeepaliveTimer.After(iStatus, KMaxTInt); + } + else + { + iRemainingTime = 0; + iNatKeepaliveTimer.After(iStatus, iNatKeepAliveInterval * 1000000); + } + SetActive(); + }