vpnengine/ikesocket/src/receiver.cpp
changeset 0 33413c0669b9
child 12 a15e6baef510
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 2008 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:  Receiver for UDP data
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <es_sock.h>
       
    20 #include "receiver.h"
       
    21 #include "ikemsgheader.h"
       
    22 #include "ikev2const.h"
       
    23 #include "ikesocketdefs.h"
       
    24 #include "ikedebug.h"
       
    25 #include "ikesocketassert.h"
       
    26 
       
    27 using namespace IkeSocket;
       
    28 
       
    29 const TInt KMaxIkePacketSize( 65536 ); // Maximum size for UDP packet
       
    30 
       
    31 // ======== MEMBER FUNCTIONS ========
       
    32 
       
    33 // ---------------------------------------------------------------------------
       
    34 // Two-phased constructor.
       
    35 // ---------------------------------------------------------------------------
       
    36 //
       
    37 CReceiver* CReceiver::NewL( RSocket& aSocket,
       
    38                             MReceiverCallback& aCallback,                                     
       
    39                             MIkeDebug& aDebug  )
       
    40     {
       
    41     CReceiver* self = new (ELeave) CReceiver( aSocket,
       
    42                                               aCallback,
       
    43                                               aDebug );  
       
    44     CleanupStack::PushL(self);
       
    45     self->ConstructL();
       
    46     CleanupStack::Pop(self);    
       
    47     return self;            
       
    48     }
       
    49 
       
    50 // ---------------------------------------------------------------------------
       
    51 // Destructor.
       
    52 // ---------------------------------------------------------------------------
       
    53 //
       
    54 CReceiver::~CReceiver()
       
    55     {
       
    56     DEBUG_LOG( _L("CReceiver::~CReceiver") );
       
    57     Cancel();
       
    58     delete iMsg;
       
    59     }
       
    60 
       
    61 // ---------------------------------------------------------------------------
       
    62 // Constructor.
       
    63 // ---------------------------------------------------------------------------
       
    64 //
       
    65 CReceiver::CReceiver( RSocket& aSocket,
       
    66                       MReceiverCallback& aCallback,
       
    67                       MIkeDebug& aDebug )
       
    68  : CActive( EPriorityStandard ),
       
    69    iState( EIdle ),
       
    70    iMsgPtr( 0, 0, 0 ),
       
    71    iSocket( aSocket ),
       
    72    iCallback( aCallback ),
       
    73    iDebug( aDebug )
       
    74     {
       
    75     CActiveScheduler::Add( this ); // Added to the Active Scheduler
       
    76     }
       
    77 
       
    78 // ---------------------------------------------------------------------------
       
    79 // Second phase construction.
       
    80 // ---------------------------------------------------------------------------
       
    81 //
       
    82 void CReceiver::ConstructL()
       
    83     {
       
    84     DEBUG_LOG( _L("CReceiver::ConstructL") );
       
    85     }
       
    86 
       
    87 // ---------------------------------------------------------------------------
       
    88 // Sets IKE major version.
       
    89 // ---------------------------------------------------------------------------
       
    90 //
       
    91 void CReceiver::SetIkeMajorVersion( const TIkeMajorVersion aIkeMajorVersion )
       
    92     {
       
    93     IKESOCKET_ASSERT( aIkeMajorVersion == EIkeMajorV1 ||
       
    94                       aIkeMajorVersion == EIkeMajorV2 );
       
    95 
       
    96     iIkeMajorVersion = aIkeMajorVersion;    
       
    97     }
       
    98 
       
    99 // ---------------------------------------------------------------------------
       
   100 // Starts receive.
       
   101 // ---------------------------------------------------------------------------
       
   102 //
       
   103 void CReceiver::Receive()
       
   104     {
       
   105     IKESOCKET_ASSERT( iIkeMajorVersion == EIkeMajorV1 ||
       
   106                       iIkeMajorVersion == EIkeMajorV2 );
       
   107 
       
   108     if ( iState == EIdle )
       
   109         {
       
   110         WaitDataAvailable();
       
   111         }
       
   112     }
       
   113 
       
   114 // ---------------------------------------------------------------------------
       
   115 // Cancels receive.
       
   116 // ---------------------------------------------------------------------------
       
   117 //
       
   118 void CReceiver::CancelReceive()
       
   119     {
       
   120     Cancel();
       
   121         
       
   122     delete iMsg;
       
   123     iMsg = NULL;
       
   124     iMsgPtr.Set( 0, 0, 0 );
       
   125     
       
   126     iState = EIdle;    
       
   127     }
       
   128 
       
   129 // ---------------------------------------------------------------------------
       
   130 // Waits for data to become available for reading.
       
   131 // ---------------------------------------------------------------------------
       
   132 //
       
   133 void CReceiver::WaitDataAvailable()
       
   134     {
       
   135     IKESOCKET_ASSERT( iState == EIdle );
       
   136     IKESOCKET_ASSERT( !IsActive() );
       
   137         
       
   138     iState = EWaitingData;
       
   139     delete iMsg;
       
   140     iMsg = NULL;
       
   141         
       
   142     iFlags() = KSockSelectRead | KSockSelectExcept;
       
   143 
       
   144     iSocket.Ioctl( KIOctlSelect,
       
   145                    iStatus,
       
   146                    &iFlags,
       
   147                    KSOLSocket );    
       
   148     SetActive();
       
   149     }
       
   150 
       
   151 // ---------------------------------------------------------------------------
       
   152 // Receives data from socket.
       
   153 // ---------------------------------------------------------------------------
       
   154 //
       
   155 void CReceiver::ReceiveDataL()
       
   156     {
       
   157     IKESOCKET_ASSERT( !IsActive() );
       
   158 
       
   159     iState = EReceiving;
       
   160         
       
   161     TInt bytesPending( 0 );
       
   162     TInt err = iSocket.GetOpt( KSOReadBytesPending,
       
   163                                KSOLSocket,
       
   164                                bytesPending );
       
   165     
       
   166     User::LeaveIfError( err );
       
   167         
       
   168     if ( bytesPending > KMaxIkePacketSize )        
       
   169         {
       
   170         // KMaxIkePacketSize (65536) is max message size supported.
       
   171         bytesPending = KMaxIkePacketSize;
       
   172         }
       
   173     
       
   174     iMsg = HBufC8::NewL( bytesPending );
       
   175     iMsgPtr.Set( iMsg->Des() );
       
   176 
       
   177     iSocket.RecvFrom( iMsgPtr,
       
   178                       iSrcAddr,
       
   179                       0,
       
   180                       iStatus );
       
   181     SetActive();
       
   182     }
       
   183 
       
   184 // ---------------------------------------------------------------------------
       
   185 // Handles receive of data.
       
   186 // ---------------------------------------------------------------------------
       
   187 //
       
   188 void CReceiver::HandleDataReceivedL() 
       
   189     {
       
   190 #ifdef _DEBUG
       
   191     TBuf<100> txt_addr;
       
   192     iSrcAddr.Output( txt_addr );
       
   193     TUint32 port = iSrcAddr.Port();
       
   194     DEBUG_LOG3( _L("CReceiver::HandleDataReceivedL, local port=%d, src address:port=%S:%d"),
       
   195             iSocket.LocalPort(), &txt_addr, port );
       
   196 #endif
       
   197     
       
   198     TInt msgLength = iMsgPtr.Length();            
       
   199     if ( msgLength <= TInt(ISAKMP_HDR_SIZE) )
       
   200         {
       
   201         // Message size smaller than header size.
       
   202         User::Leave( KErrArgument ); 
       
   203         }
       
   204         
       
   205     // Check if <non-ESP marker> is in the beginning of IKE message.
       
   206     // <non-ESP marker> is related to the NAT traversal and it should
       
   207     // exist only if IKE messages received through port 4500.
       
   208     // However, we accept <non-ESP marker> also in IKE message
       
   209     // received through normal IKE port (500).
       
   210     const ThdrISAKMP* ikeHdr = ThdrISAKMP::Ptr( iMsgPtr );
       
   211     TUint32 octets = BigEndian::Get32( (TUint8*)(ikeHdr) );
       
   212     TBool nonEspMarker = ( octets == NON_ESP_MARKER );
       
   213     if ( nonEspMarker )
       
   214         {                
       
   215         ikeHdr = ikeHdr->GotoOffset( NON_ESP_MARKER_SIZE );
       
   216         msgLength -= NON_ESP_MARKER_SIZE;        
       
   217         if ( msgLength <= TInt(ISAKMP_HDR_SIZE) )
       
   218             {
       
   219             // Message size smaller than header size.
       
   220             User::Leave( KErrArgument ); 
       
   221             }
       
   222         }
       
   223     
       
   224     // Because the received data can be any UDP data transmitted to
       
   225     // IKE port(s), some checks are done before packet is processed. Length   
       
   226     // value read from header must be greater than ISAKMP_HDR_SIZE.
       
   227     TInt ikeMsgLength = ikeHdr->GetLength();        
       
   228     if ( ikeMsgLength <= TInt(ISAKMP_HDR_SIZE) )
       
   229         {
       
   230         User::Leave( KErrArgument );        
       
   231         }
       
   232 
       
   233     // IKE major version in packet MUST be as client expects (1 or 2).
       
   234     TUint8 majorVersion = ikeHdr->GetMajorVersion();
       
   235     if ( majorVersion != iIkeMajorVersion )
       
   236         {
       
   237         User::Leave( KErrArgument );
       
   238         }
       
   239       
       
   240     NotifyDataReceived();    
       
   241     }
       
   242 
       
   243 // ---------------------------------------------------------------------------
       
   244 // Handles error in receiving.
       
   245 // ---------------------------------------------------------------------------
       
   246 //
       
   247 void CReceiver::HandleError( const TInt aStatus )
       
   248     {
       
   249     DEBUG_LOG1( _L("CReceiver::HandleError, aStatus=%d"), aStatus );
       
   250     
       
   251     delete iMsg;
       
   252     iMsg = NULL;
       
   253     iMsgPtr.Set( 0, 0, 0 );
       
   254     iState = EIdle;
       
   255     
       
   256     if ( aStatus == KErrDied ||
       
   257          aStatus == KErrServerTerminated ||
       
   258          aStatus == KErrNoMemory )
       
   259         {
       
   260         // Fatal error. Notify client.
       
   261         iCallback.ReceiveError( aStatus );
       
   262         }
       
   263     else
       
   264         {
       
   265         // Error is not fatal. Restart receiving
       
   266         Receive();
       
   267         }
       
   268     }
       
   269 
       
   270 // ---------------------------------------------------------------------------
       
   271 // Notifies client that data has been received.
       
   272 // ---------------------------------------------------------------------------
       
   273 //
       
   274 void CReceiver::NotifyDataReceived()
       
   275     {
       
   276     TInetAddr srcAddr = iSrcAddr;
       
   277     TInt localPort = iSocket.LocalPort();
       
   278     HBufC8* msg = iMsg;
       
   279 
       
   280     iMsg = NULL;
       
   281     iMsgPtr.Set( 0, 0, 0 );
       
   282     iState = EIdle;
       
   283     
       
   284     // Continue receiving.
       
   285     Receive();
       
   286         
       
   287     iCallback.DataReceived( msg, // Ownership transferred
       
   288                             srcAddr,
       
   289                             localPort );
       
   290     }
       
   291 
       
   292 // ---------------------------------------------------------------------------
       
   293 // From CActive
       
   294 // Handles a leave occurring in RunL().
       
   295 // ---------------------------------------------------------------------------
       
   296 //
       
   297 TInt CReceiver::RunError( TInt aError )
       
   298     {
       
   299     HandleError( aError );    
       
   300     return KErrNone;
       
   301     }
       
   302 
       
   303 // ---------------------------------------------------------------------------
       
   304 // From CActive
       
   305 // Handles request completion event about available data or received data.
       
   306 // ---------------------------------------------------------------------------
       
   307 //
       
   308 void CReceiver::RunL()
       
   309     {
       
   310     IKESOCKET_ASSERT( iState == EWaitingData ||
       
   311                       iState == EReceiving );
       
   312     DEBUG_LOG2( _L("CReceiver::RunL, iState=%d, iStatus=%d"),
       
   313             iState, iStatus.Int() );    
       
   314     
       
   315     if ( iStatus.Int() )
       
   316         {
       
   317         HandleError( iStatus.Int() );
       
   318         return;
       
   319         }
       
   320     
       
   321     switch ( iState )
       
   322         {
       
   323         case EWaitingData:
       
   324             {
       
   325             ReceiveDataL();
       
   326             break;
       
   327             }
       
   328         case EReceiving:
       
   329             {
       
   330             HandleDataReceivedL();
       
   331             break;
       
   332             }
       
   333         default:
       
   334             break;
       
   335         }
       
   336     }
       
   337 
       
   338 // ---------------------------------------------------------------------------
       
   339 // From CActive
       
   340 // Implements cancellation of an active request.
       
   341 // ---------------------------------------------------------------------------
       
   342 //
       
   343 void CReceiver::DoCancel()
       
   344     {
       
   345     IKESOCKET_ASSERT( iState == EWaitingData ||
       
   346             iState == EReceiving );
       
   347     DEBUG_LOG1( _L("CReceiver::DoCancel, iState=%d"),
       
   348             iState );
       
   349 
       
   350     switch ( iState )
       
   351         {
       
   352         case EWaitingData:
       
   353             {
       
   354             iSocket.CancelIoctl();
       
   355             break;
       
   356             }
       
   357         case EReceiving:
       
   358             {
       
   359             iSocket.CancelRecv();
       
   360             break;
       
   361             }
       
   362         default:
       
   363             break;
       
   364         }
       
   365     }