--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/networksecurity/tls/protocol/applicationdata.cpp Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,290 @@
+// Copyright (c) 2003-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:
+// SSL3.0 and TLS1.0 Application Data source file.
+// Describes the implementation of the Application data (transmission
+// and reception) state machines.
+//
+//
+
+/**
+ @file
+*/
+
+#include "applicationdata.h"
+#include "tlsconnection.h"
+#include "recordprotocolevents.h"
+#include "AlertProtocolEvents.h"
+#include "hellorequest.h"
+
+
+CSendAppData* CSendAppData::NewL( CRecordComposer& aRecordComposer )
+{
+ LOG(Log::Printf(_L("CSendAppData::NewL()"));)
+ CSendAppData* self = new(ELeave) CSendAppData( aRecordComposer );
+ LOG(Log::Printf(_L("self %x - %x"), self, (TUint)self + sizeof( CSendAppData ));)
+ CleanupStack::PushL( self );
+ self->ConstructL( aRecordComposer );
+ CleanupStack::Pop();
+ return self;
+}
+
+inline CSendAppData::CSendAppData( CRecordComposer& aRecordComposer ) :
+ iRecordComposer( aRecordComposer )
+{
+ LOG(Log::Printf(_L("CSendAppData::CSendAppData()\n"));)
+ iHistory = KTlsApplicationData; // This shows explicitly where we are
+}
+
+CSendAppData::~CSendAppData()
+{
+ LOG(Log::Printf(_L("CSendAppData::~CSendAppData()\n"));)
+ SetSockXfrLength( NULL );
+ Cancel( KErrNone );
+ delete iSendAlert;
+}
+
+inline void CSendAppData::ConstructL( CRecordComposer& aRecordComposer )
+{
+ iSendAlert = new(ELeave)CSendAlert( *this, aRecordComposer );
+ LOG(Log::Printf(_L("CSendAppData::ConstructL() %x\n"), SendAlert());)
+ ResumeL();
+}
+
+void CSendAppData::Suspend()
+{
+ LOG(Log::Printf(_L("CSendAppData::Suspend()\n"));)
+
+ iCurrentPos = iRecordComposer.CurrentPos();
+ iAppData = iRecordComposer.UserData();
+ iRecordComposer.SetUserData( NULL );
+}
+
+void CSendAppData::ResumeL()
+{
+ LOG(Log::Printf(_L("CSendAppData::ResumeL()\n"));)
+
+ iRecordComposer.SetUserData( iAppData );
+ iRecordComposer.ReConstructL( this, iCurrentPos ); //it sets record type to ETlsAppDataContentType
+ iCurrentPos = 0;
+
+ if ( !iActiveEvent )
+ { //active event is the record composer
+ iActiveEvent = &iRecordComposer;
+ }
+}
+
+void CSendAppData::SetSockXfrLength( TInt* aLen )
+{
+ LOG(Log::Printf(_L("CSendAppData::SetSockXfrLength()\n"));)
+
+ iSockXfrLength = aLen;
+ if ( iSockXfrLength )
+ {
+ *iSockXfrLength = 0;
+ }
+}
+
+void CSendAppData::OnCompletion()
+{
+ LOG(Log::Printf(_L("CSendAppData::OnCompletion()\n"));)
+
+ TDesC8* pAppData = iRecordComposer.UserData();
+ if ( pAppData ) //could have finished via an error
+ {
+ if ( iSockXfrLength )
+ {
+ *iSockXfrLength = iRecordComposer.CurrentPos();
+ }
+ if ( iLastError == KErrNone && iStatus.Int() == KErrNone )
+ {
+ //hello request received?
+ if ( iStateMachineNotify == iHelloReq && iHelloReq )
+ {//no user request completion, signal to hello request
+ iHelloReq->OnCompletion( this );
+ return;
+ }
+ // Anything more to send?
+ else if ( pAppData->Length() > iRecordComposer.CurrentPos() )
+ { // No error (cancel) && still some app data in the app buffer =>
+ // => write another fragment
+ iActiveEvent = &iRecordComposer;
+ Start( iClientStatus, iStateMachineNotify );
+ return;
+ }
+ }
+ }
+
+ iRecordComposer.SetUserData( NULL ); //we'r finished
+ iRecordComposer.ResetCurrentPos();
+
+ /* Fix for the TLS Client hang issue DEF130128.
+ * In the case of where one of the state machines receives the
+ * asynchronous event alert due to TLS server reset, the state
+ * machine triggers the cleanup activities. The TlsConnection
+ * fails to clean up the resources allocated for handling data
+ * transfer and TLS handshake in such cases if one of the state
+ * machines has issued the asynchronous server request and is
+ * waiting for the request to complete. The change made below
+ * will allow the code complete the pending status in such cases
+ * and allow the cleanup to proceed.
+ */
+ if ( iStatus.Int() == KRequestPending )
+ {
+ TRequestStatus* p=&iStatus;
+ User::RequestComplete( p, iLastError );
+ }
+ /* End of fix for the TLS Client hang issue DEF130128. */
+
+ CStateMachine::OnCompletion();
+}
+
+void CSendAppData::DoCancel()
+{
+ LOG(Log::Printf(_L("CSendAppData::DoCancel()\n"));)
+
+ iLastError = KErrCancel;
+ iRecordComposer.CancelAll();
+ CStateMachine::DoCancel();
+}
+
+//
+//
+CRecvAppData* CRecvAppData::NewL( CTlsConnection& aTlsConnection )
+{
+ LOG(Log::Printf(_L("CRecvAppData::NewL()"));)
+ CRecvAppData* self = new(ELeave) CRecvAppData( aTlsConnection );
+ LOG(Log::Printf(_L("self %x - %x"), self, (TUint)self + sizeof( CRecvAppData ));)
+ CleanupStack::PushL( self );
+ self->ConstructL( aTlsConnection );
+ CleanupStack::Pop();
+ return self;
+}
+
+inline CRecvAppData::CRecvAppData( CTlsConnection& aTlsConnection ) :
+ iHeldData( 0, 0 ),
+ iRecordParser( aTlsConnection.RecordParser() )
+{
+ LOG(Log::Printf(_L("CRecvAppData::CRecvAppData()\n"));)
+ iHistory = KTlsApplicationData; // This shows explicitly where we are
+}
+
+CRecvAppData::~CRecvAppData()
+{
+ LOG(Log::Printf(_L("CRecvAppData::~CRecvAppData()\n"));)
+ SetSockXfrLength( NULL );
+ Cancel( KErrNone );
+ delete iSendAlert;
+}
+
+inline void CRecvAppData::ConstructL( CTlsConnection& aTlsConnection )
+{
+ iSendAlert = new(ELeave)CSendAlert( *this, aTlsConnection.RecordComposer() );
+ LOG(Log::Printf(_L("CRecvAppData::ConstructL() %x\n"), SendAlert());)
+ ResumeL( aTlsConnection );
+}
+
+void CRecvAppData::Suspend()
+{
+ LOG(Log::Printf(_L("CRecvAppData::Suspend()\n"));)
+
+ iHeldData = iRecordParser.HeldData();
+ iAppData = iRecordParser.UserData();
+ iRecordParser.SetUserData( NULL );
+ iRecordParser.SetUserMaxLength( 0 );
+}
+
+void CRecvAppData::ResumeL( CTlsConnection& aTlsConnection )
+{
+ LOG(Log::Printf(_L("CRecvAppData::ResumeL()"));)
+
+ __ASSERT_DEBUG( (iAppData && iClientStatus) || (!iAppData && !iClientStatus), TlsPanic(ETlsPanicAppDataResumeButNotStarted));
+ __ASSERT_DEBUG( iSendAlert, TlsPanic(ETlsPanicAlertReceived));
+ iRecordParser.SetUserData( iAppData );
+ iRecordParser.SetUserMaxLength( iAppData ? iAppData->MaxLength() : 0 );
+ iRecordParser.ReConstructL( this, iHeldData, *iSendAlert );
+
+ // Destroy the Rx list & add the only handshake event accepted during application data mode.
+ CHandshakeParser* pParser = iRecordParser.HandshakeParser();
+ pParser->DestroyRxList();
+ CHelloRequest* helloReq = new(ELeave)CHelloRequest( aTlsConnection, *this );
+ //coverity[leave_without_push]
+ LOG(Log::Printf(_L("helloReq %x - %x"), helloReq, (TUint)helloReq + sizeof( CHelloRequest ));)
+ pParser->AddToList( *helloReq );
+
+ aTlsConnection.SendAppData()->SetHelloRequest( helloReq ); //no ownership passed
+ if ( !iActiveEvent )
+ { //active event is the record parser
+ iActiveEvent = &iRecordParser;
+ }
+}
+
+void CRecvAppData::OnCompletion()
+{
+ LOG(Log::Printf(_L("CRecvAppData::OnCompletion()\n"));)
+
+ if ( iLastError == KErrNone && iStatus.Int() == KErrNone )
+ {
+ if ( iRecordParser.TlsRecordType() == ETlsHandshakeContentType )
+ {//it could be just hello request received => suspend() could have already happened
+ return;
+ }
+ TDes8* pAppData = iRecordParser.UserData();
+ if ( pAppData ) //could have finished via an error
+ {
+ if ( iSockXfrLength && pAppData->Length() ) //are we to report RecvOneOrMore?
+ { //yes and finish
+ *iSockXfrLength = pAppData->Length();
+ }
+ else if ( pAppData->Length() < pAppData->MaxLength() )
+ { //no error (cancel) && still some free room in the app data buffer =>
+ //=> read another fragment
+ iActiveEvent = &iRecordParser;
+ Start( iClientStatus, iStateMachineNotify );
+ return;
+ }
+ }
+ }
+
+ iRecordParser.SetUserData( NULL ); //we'r finished
+ iRecordParser.SetUserMaxLength( 0 );
+
+ /* Fix for the TLS Client hang issue DEF130128.
+ * In the case of where one of the state machines receives the
+ * asynchronous event alert due to TLS server reset, the state
+ * machine triggers the cleanup activities. The TlsConnection
+ * fails to clean up the resources allocated for handling data
+ * transfer and TLS handshake in such cases if one of the state
+ * machines has issued the asynchronous server request and is
+ * waiting for the request to complete. The change made below
+ * will allow the code complete the pending status in such cases
+ * and allow the cleanup to proceed.
+ */
+ if ( iStatus.Int() == KRequestPending )
+ {
+ TRequestStatus* p=&iStatus;
+ User::RequestComplete( p, iLastError );
+ }
+ /* End of fix for the TLS Client hang issue DEF130128. */
+
+ CStateMachine::OnCompletion();
+}
+
+void CRecvAppData::DoCancel()
+{
+ LOG(Log::Printf(_L("CRecvAppData::DoCancel()\n"));)
+
+ iLastError = KErrCancel;
+ iRecordParser.CancelAll();
+ CStateMachine::DoCancel();
+}