vpnengine/ikev2lib/src/ikev2messagesendqueue.cpp
changeset 0 33413c0669b9
child 3 2df28d7a2299
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:  IKEv2 IKE message send que.
       
    15 *
       
    16 */
       
    17 
       
    18 #include "ikev2messagesendqueue.h"
       
    19 #include "ikemsgheader.h"
       
    20 #include "ikedebug.h"
       
    21 
       
    22 _LIT8(KKeepaliveData, 0xff);
       
    23 
       
    24 CIkev2MessageSendQueue* CIkev2MessageSendQueue::NewL(MIkeDataInterface& aDataInterface,
       
    25                                                      const TInetAddr& aDestinationAddress,
       
    26                                                      TUint8 aDscp,
       
    27                                                      TUint aNatKeepAliveInterval,
       
    28                                                      MIkeDebug& aDebug)
       
    29     {
       
    30     CIkev2MessageSendQueue* self = new (ELeave) CIkev2MessageSendQueue(aDataInterface,
       
    31                                                                        aDestinationAddress,
       
    32                                                                        aDscp,
       
    33                                                                        aNatKeepAliveInterval,
       
    34                                                                        aDebug);
       
    35     CleanupStack::PushL(self);
       
    36     self->ConstructL();
       
    37     CleanupStack::Pop(self);
       
    38     
       
    39     return self;
       
    40     }
       
    41 
       
    42 
       
    43 CIkev2MessageSendQueue::CIkev2MessageSendQueue(MIkeDataInterface& aDataInterface,
       
    44                                                const TInetAddr& aDestinationAddress,
       
    45                                                TUint8 aDscp,
       
    46                                                TUint aNatKeepAliveInterval,
       
    47                                                MIkeDebug& aDebug)
       
    48 :CActive(EPriorityStandard), 
       
    49  iDataInterface(aDataInterface), 
       
    50  iNatKeepAliveInterval(aNatKeepAliveInterval),
       
    51  iDestinationAddress(aDestinationAddress),
       
    52  iDscp(aDscp),
       
    53  iDebug(aDebug)
       
    54     {
       
    55     CActiveScheduler::Add(this);
       
    56     
       
    57     if (iNatKeepAliveInterval == 0)
       
    58         {
       
    59         iNatKeepAliveInterval = 120;
       
    60         }
       
    61     }
       
    62 
       
    63 
       
    64 void CIkev2MessageSendQueue::ConstructL()
       
    65     {
       
    66     iSender = CIkev2Sender::NewL( iDataInterface,
       
    67                                   *this);        
       
    68     User::LeaveIfError(iNatKeepaliveTimer.CreateLocal());
       
    69     }
       
    70 
       
    71 
       
    72 CIkev2MessageSendQueue::~CIkev2MessageSendQueue()
       
    73     {
       
    74     Cancel();
       
    75     iNatKeepaliveTimer.Close();
       
    76     iSasBehindNat.Close();
       
    77     delete iSender;
       
    78     iIkeMsgSendBuffer.Reset();
       
    79     iIkeMsgSendBuffer.Close();
       
    80     }
       
    81 
       
    82 void CIkev2MessageSendQueue::SendIkeMessageL(const TPtrC8 aIkeMsg, 
       
    83                                              TBool aFloatedPort)
       
    84     {        
       
    85     Cancel();
       
    86     if (!iSender->IsActive())
       
    87         {        
       
    88         iIkeMsgInSending.Set(aIkeMsg);
       
    89         TUint port = (aFloatedPort) ? FLOATED_IKE_PORT : IKE_PORT;
       
    90 
       
    91 #ifdef _DEBUG
       
    92         TBuf<80> destAddr;
       
    93         iDestinationAddress.Output(destAddr);
       
    94         DEBUG_LOG3(_L("No sending active. Message sent immediately to %S:%d DSCP=%d."), &destAddr, port, iDscp);
       
    95 #endif //_DEBUG        
       
    96         iDestinationAddress.SetPort(port);
       
    97         iSender->SendIkeMsg(port, iDestinationAddress, iDscp, iIkeMsgInSending);        
       
    98         }
       
    99     else
       
   100         {
       
   101         DEBUG_LOG(_L("Sending in progress, message added to send queue."));
       
   102         TIkeMsgWaitQueueObject waitObject = { aIkeMsg, aFloatedPort };
       
   103         User::LeaveIfError(iIkeMsgSendBuffer.Append(waitObject));
       
   104         }
       
   105     }
       
   106 
       
   107 
       
   108 void CIkev2MessageSendQueue::CancelSend(const TPtrC8& aIkeMsg)
       
   109     {
       
   110     DEBUG_LOG(_L("Sending of one datagram canceled."));
       
   111     if (aIkeMsg.Ptr() == iIkeMsgInSending.Ptr())
       
   112         {
       
   113         __ASSERT_DEBUG(iSender->IsActive(), User::Invariant());
       
   114         //The NAT keepalive timer should not be active, because sending
       
   115         //is in progress.
       
   116         __ASSERT_DEBUG(!IsActive(), User::Invariant()); 
       
   117         iSender->Cancel();
       
   118         iIkeMsgInSending.Set(NULL, 0);
       
   119         // Send next message from queue.    
       
   120         SendIkeMsgCompleted( KErrCancel );
       
   121         }
       
   122     else
       
   123         {        
       
   124         for (TUint i = 0; i < iIkeMsgSendBuffer.Count(); ++i)
       
   125             {
       
   126             if (iIkeMsgSendBuffer[i].iIkeMsg.Ptr() == aIkeMsg.Ptr())
       
   127                 {
       
   128                 iIkeMsgSendBuffer.Remove(i);
       
   129                 break;
       
   130                 }            
       
   131             }        
       
   132         }              
       
   133     }
       
   134 
       
   135 void CIkev2MessageSendQueue::SendIkeMsgCompleted( TInt /*aStatus*/ )
       
   136     {
       
   137     DEBUG_LOG(_L("Ike message send complete."));
       
   138     iIkeMsgInSending.Set(NULL, 0);
       
   139     
       
   140     if (iIkeMsgSendBuffer.Count() > 0)
       
   141         {
       
   142         TIkeMsgWaitQueueObject& waitObject = iIkeMsgSendBuffer[0];
       
   143         TUint port = (waitObject.iFloatedPort) ? FLOATED_IKE_PORT : 500;
       
   144         iSender->SendIkeMsg(port, iDestinationAddress, iDscp, waitObject.iIkeMsg);
       
   145         iIkeMsgSendBuffer.Remove(0);
       
   146         iIkeMsgInSending.Set(waitObject.iIkeMsg);
       
   147         }
       
   148     else if (iSasBehindNat.Count() > 0 && iNatKeepAliveInterval > 0)
       
   149         {
       
   150         ArmKeepaliveTimer();
       
   151         }
       
   152     }
       
   153 
       
   154 
       
   155 void CIkev2MessageSendQueue::CancelAll()
       
   156     {
       
   157     iSender->Cancel();
       
   158     iIkeMsgSendBuffer.Reset();
       
   159     }
       
   160 
       
   161 
       
   162 void CIkev2MessageSendQueue::NewSaBehindNatL(TUint aSaId)
       
   163     {
       
   164     DEBUG_LOG1(_L("CIkev2MessageSendQueue::NewSaBehindNatL: SaId=%d"), aSaId);
       
   165     __ASSERT_DEBUG(iSasBehindNat.Find(aSaId) == KErrNotFound, User::Invariant());
       
   166     User::LeaveIfError(iSasBehindNat.Append(aSaId));    
       
   167     if (!iSender->IsActive() && iNatKeepAliveInterval > 0)
       
   168         {
       
   169         //No sending acticve arm the nat keepalive timer.
       
   170         ArmKeepaliveTimer();
       
   171         }
       
   172     }
       
   173 
       
   174 
       
   175 void CIkev2MessageSendQueue::SaBehindNatDeleted(TUint aSaId)
       
   176     {
       
   177     DEBUG_LOG1(_L("CIkev2MessageSendQueue::SaBehindNatDeleted: SaId=%d"), aSaId);
       
   178     TInt index = iSasBehindNat.Find(aSaId);
       
   179     __ASSERT_DEBUG(index >= 0, User::Invariant());
       
   180     iSasBehindNat.Remove(index);   
       
   181     if (iSasBehindNat.Count() == 0)
       
   182         {
       
   183         //Cancel keepalive timer
       
   184         Cancel();
       
   185         }
       
   186     }
       
   187 
       
   188 void CIkev2MessageSendQueue::RunL()
       
   189     {
       
   190     //Send the NAT keepalive
       
   191     
       
   192     __ASSERT_DEBUG(!iSender->IsActive(), User::Invariant());
       
   193     __ASSERT_DEBUG(iSasBehindNat.Count() > 0 && iNatKeepAliveInterval > 0, User::Invariant());
       
   194     
       
   195     if (iRemainingTime == 0)
       
   196         {
       
   197         DEBUG_LOG(_L("Sending NAT keepalive"));
       
   198         iSender->SendIkeMsg(FLOATED_IKE_PORT, iDestinationAddress, iDscp, KKeepaliveData);
       
   199         }
       
   200     else if (iRemainingTime > KMaxTInt/1000000)
       
   201         {
       
   202         iRemainingTime -= KMaxTInt/1000000;
       
   203         iNatKeepaliveTimer.After(iStatus, KMaxTInt);
       
   204         SetActive();
       
   205         }
       
   206     else
       
   207         {        
       
   208         iNatKeepaliveTimer.After(iStatus, iRemainingTime*1000000);
       
   209         iRemainingTime = 0;
       
   210         SetActive();
       
   211         }
       
   212     }
       
   213 
       
   214 void CIkev2MessageSendQueue::DoCancel()
       
   215     {    
       
   216     iNatKeepaliveTimer.Cancel();
       
   217     iRemainingTime = 0;
       
   218     DEBUG_LOG(_L("Keepalive timer canceled"));
       
   219     }
       
   220 
       
   221 void CIkev2MessageSendQueue::ArmKeepaliveTimer()
       
   222     {
       
   223     DEBUG_LOG(_L("CIkev2MessageSendQueue::ArmKeepaliveTimer"));    
       
   224     //Arm NAT keepalive timer.
       
   225     if (iNatKeepAliveInterval > KMaxTInt/1000000 ) 
       
   226         {
       
   227         iRemainingTime = iNatKeepAliveInterval - KMaxTInt/1000000;
       
   228         iNatKeepaliveTimer.After(iStatus, KMaxTInt);
       
   229         }
       
   230     else
       
   231         {
       
   232         iRemainingTime = 0;
       
   233         iNatKeepaliveTimer.After(iStatus, iNatKeepAliveInterval * 1000000);
       
   234         }        
       
   235     SetActive();    
       
   236     }