--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/natfw/natfwstunturnclient/inc/cstuntransaction.h Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,442 @@
+/*
+* Copyright (c) 2006 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:
+*
+*/
+
+
+
+
+#ifndef C_CSTUNTRANSACTION_H
+#define C_CSTUNTRANSACTION_H
+
+// INCLUDES
+#include <e32base.h>
+#include <in_sock.h>
+#include "mnatfwunsafudpsenderobserver.h"
+#include "cstuntimeruser.h"
+#include "cnatfwunsafmediaconnsender.h"
+#include "mncmsenderobserver.h"
+#include "natfwstunclientdefs.h"
+
+// FORWARD DECLARATIONS
+class RSocket;
+class CNATFWUNSAFMessage;
+class CNATFWUNSAFBindingRequest;
+class CNATFWUNSAFUnknownAttributesAttribute;
+class CNATFWUNSAFUdpSender;
+class MSTUNTransactionObserver;
+class MNcmConnectionMultiplexer;
+
+// CLASS DECLARATION
+
+/**
+ * This class presents a single STUN transaction.
+ */
+class CSTUNTransaction :
+ public CSTUNTimerUser,
+ public MNATFWUNSAFUdpSenderObserver,
+ public MNcmSenderObserver
+ {
+
+ friend class ut_cstuntransaction;
+
+ public: // Constructors and destructor
+
+ /**
+ * Creates a new instance of CSTUNTransaction
+ * @pre aAddress.IsUnspecified() == EFalse
+ * @param aSocket UDP socket to use
+ * @param aAddress STUN server's address where the request is sent to
+ * @param aSharedSecret Shared secret to be used to calculate
+ * a hash over the encoded UNSAF message.
+ * @param aObserver An observer to receive callbacks
+ * @param aTimer Timer provider
+ * @param aRetransmitInterval Initial retransmission interval
+ * @param aTransportProtocol Used transport protocol.
+ * @return A new instance of CSTUNTransaction, ownership is transferred.
+ */
+ static CSTUNTransaction*
+ NewL( CNATFWUNSAFMessage& aRequest,
+ const TInetAddr& aAddress,
+ const TDesC8& aSharedSecret,
+ RSocket& aSocket,
+ CDeltaTimer& iTimer,
+ TInt aRetransmitInterval,
+ MSTUNTransactionObserver& aObserver,
+ const TDesC8& aProtocol,
+ TTransportProtocol aTransportProtocol );
+
+ /**
+ * Overload version of NewL
+ *
+ * Creates a new instance of CSTUNTransaction
+ * @pre aAddress.IsUnspecified() == EFalse
+ * @param aRequest Binding Request message
+ * @param aAddress STUN server's address where the request is sent to
+ * @param aSharedSecret Shared secret to be used to calculate
+ * a hash over the encoded UNSAF message.
+ * @param aStreamId Used natfw stream id
+ * @param aSubstreamId Used natfw stream related sub stream id
+ * @param aTimer Timer provider
+ * @param aRetransmitInterval Initial retransmission interval
+ * @param aObserver An observer to receive callbacks
+ * @param aProtocol Used protocol, either "stun" or "stun-relay"
+ * @param aMux instance of connection multiplexer
+ * @param aTransportProtocol Used transport protocol.
+ * @param aUseFingerprint ETrue if fingerprint is added to request
+ * @param aDestAddr Destination address
+ * @return A new instance of CSTUNTransaction, ownership is transferred.
+ */
+ static CSTUNTransaction*
+ NewL( CNATFWUNSAFMessage& aRequest,
+ const TInetAddr& aAddress,
+ const TDesC8& aSharedSecret,
+ TUint aStreamId,
+ TUint aSubstreamId,
+ CDeltaTimer& aTimer,
+ TInt aRetransmitInterval,
+ MSTUNTransactionObserver& aObserver,
+ const TDesC8& aProtocol,
+ MNcmConnectionMultiplexer& aMux,
+ TTransportProtocol aTransportProtocol,
+ TBool aUseFingerprint=EFalse,
+ const TInetAddr& aDestAddr=KAFUnspec );
+
+ ~CSTUNTransaction();
+
+ public: // From CSTUNTimerUser
+
+ void TimerExpiredL();
+
+ void LeaveFromTimerExpired( TInt aError );
+
+ public: // From MUNSAFUdpSenderObserver
+
+ void UNSAFUdpMessageSentL();
+
+ void UNSAFUdpMessageFailure( TInt aError );
+
+ public: // From MNcmSenderObserver
+
+ void MessageSent();
+
+ void MessageSentFailure( TInt aError );
+
+ public: // New functions
+
+ void SendRequestL();
+
+ void RetransmitRequestL();
+
+ /**
+ * Transaction receives a Binding (Error) Response message.
+ * @pre aResponse.Type() == CUNSAFMessage::EBindingResponse ||
+ * aResponse.Type() == CUNSAFMessage::EBindingErrorResponse
+ * @param aResponse STUN message, either a Binding Response or a
+ * Binding Error Response
+ * @param aByteStream Same STUN message as aResponse, but in undecoded
+ * format.
+ */
+ void ReceiveL( CNATFWUNSAFMessage& aResponse, const TDesC8& aByteStream );
+
+ /**
+ * Transaction has encountered an error and enters terminated state.
+ * @param aError Error reason. If transaction ends successfully, value
+ * is KErrNone.
+ */
+ void Terminate( TInt aError );
+
+ /**
+ * TimerValue can be queried. This timer value is from
+ * SetActiveDestinationResponse TIMERVAL attribute.
+ *
+ * @since s60 3.2
+ * @return timer value
+ */
+ const TUint32& TimerValue() const;
+
+ /**
+ * ICE specific cancel for stopping ongoing message retransmission.
+ * Response is waited as long as sending timer expires. After that
+ * client will be notified with error response.
+ *
+ * @since s60 3.2
+ * @return void
+ */
+ void CancelRetransmission();
+
+
+ private: // Enumerations
+
+ enum TRetransmissionCount
+ {
+ // Maximum amount of Binding Requests to send
+ KMaxRequestSentCount = 7 // rfc3489bis-06#section-7.1
+ };
+
+ private: // Constructors
+
+ CSTUNTransaction( CNATFWUNSAFMessage& aRequest,
+ const TInetAddr& aAddress,
+ const TDesC8& aSharedSecret,
+ CDeltaTimer& iTimer,
+ TInt aRetransmitInterval,
+ MSTUNTransactionObserver& aObserver,
+ TTransportProtocol aTransportProtocol );
+
+ CSTUNTransaction( CNATFWUNSAFMessage& aRequest,
+ const TInetAddr& aAddress,
+ const TDesC8& aSharedSecret,
+ TUint aStreamId,
+ TUint aSubstreamId,
+ CDeltaTimer& iTimer,
+ TInt aRetransmitInterval,
+ MSTUNTransactionObserver& aObserver,
+ const TInetAddr& aDestAddr,
+ TTransportProtocol aTransportProtocol,
+ TBool aUseFingerprint );
+
+ CSTUNTransaction();
+
+ CSTUNTransaction( const CSTUNTransaction& aTransaction );
+
+ void ConstructL( RSocket& aSocket, const TDesC8& aProtocol );
+
+ void ConstructL( const TDesC8& aProtocol,
+ MNcmConnectionMultiplexer& aMux );
+
+ private: // New functions, for internal use
+
+ /**
+ * Return the current retransmission interval in milliseconds.
+ * @return Retransmission interval
+ */
+ TInt RetransmitInterval();
+
+ /**
+ * Computes how long transaction waits for response after it has received
+ * a Binding Error Response with response code 100-399.
+ * @return Duration in milliseconds.
+ */
+ TInt ComputeWaitDuration();
+
+ /**
+ * Determines if the response should be ignored or processed.
+ * @param aResponse STUN Binding (Error) Response
+ * @return ETrue Response must be ignored, EFalse otherwise
+ */
+ TBool ShouldIgnoreResponse( const CNATFWUNSAFMessage& aResponse ) const;
+
+ /**
+ * Determines if the response should be ignored or processed.
+ * @pre aResponse.Type() == CUNSAFMessage::EBindingResponse ||
+ * aResponse.Type() == CUNSAFMessage::EBindingErrorResponse
+ * @param aResponse STUN message, either a Binding Response or a
+ * Binding Error Response
+ * @param aByteStream Same STUN message as aResponse, but in undecoded
+ * format.
+ * @return KErrNone if transaction ends successfully, 400-699 if a
+ * Binding Error Response was received, or a system wide error
+ * code.
+ */
+ TInt ProcessResponseL( CNATFWUNSAFMessage& aResponse,
+ const TDesC8& aByteStream );
+
+ /**
+ * Verify the integrity of a Binding Response.
+ * @pre aResponse.Type() == CUNSAFMessage::EBindingResponse
+ * @param aResponse Binding Response
+ * @param aByteStream Same message as aResponse, but in undecoded format
+ * @return KErrNone If integrity check succeeded
+ * ERetryAfterAddingXorOnly If integrity fails because a NAT has
+ * overwritten ip-address in MAPPED-ADDRESS.
+ * KErrCorrupt Integrity fails for some other reason.
+ */
+ TInt CheckIntegrityL( const CNATFWUNSAFMessage& aResponse,
+ const TDesC8& aByteStream );
+
+ /**
+ * Check if the Binding Response has a different MAPPED-ADDRESS or
+ * XOR-MAPPED-ADDRESS from the ones that have been received earlier.
+ * @pre aResponse.Type() == CUNSAFMessage::EBindingResponse
+ * @param aResponse STUN Binding Response
+ * @return ETrue The address in MAPPED-ADDRESS or XOR-MAPPED-ADDRESS of
+ * the aResponse differs from the earlier address.
+ * EFalse otherwise
+ */
+ TBool AddressDiffersL( const CNATFWUNSAFMessage& aResponse ) const;
+
+ /**
+ * Determines if the message integrity check failed because of a NAT has
+ * overwritten the IP-address in the MAPPED-ADDRESS.
+ * @pre aResponse.Type() == CUNSAFMessage::EBindingResponse
+ * @param aResponse STUN Binding Response
+ * @return ETrue NAT probably overwrote the IP-address in MAPPED-ADDRESS
+ * EFalse Integrity check failed for some other reason
+ */
+ TBool CheckForNatOverwriteL( const CNATFWUNSAFMessage& aResponse );
+
+ /**
+ * Gets the response code value from a ERROR-CODE attribute of the
+ * aResponse.
+ * @param aResponse UNSAF Binding Response or UNSAF Binding Error
+ * Response
+ * @return Response code, or KErrNotFound if ERROR-CODE was not present.
+ */
+ TInt GetResponseCode( const CNATFWUNSAFMessage& aResponse ) const;
+
+ /**
+ * Checks if used protocol is valid. Will leave with KErrArgument
+ * if protocol is not valid.
+ *
+ * @since s60 3.2
+ * @param aProtocol Used protocol ("stun" or "stun-relay").
+ * @return void
+ */
+ void CheckProtocolL( const TDesC8& aProtocol );
+
+ /**
+ * Gets the response code value from a ERROR-CODE attribute of the
+ * aResponse.
+ *
+ * @since s60 3.2
+ * @return true if relay used
+ */
+ TBool StunRelayUsed();
+
+ /**
+ * Method for new RTT sample measuring
+ *
+ * @since s60 3.2
+ * @return void
+ */
+ void MeasureNewRTTSample();
+
+
+ private: // Data
+
+ MSTUNTransactionObserver& iObserver;
+
+ // Binding Request message. Not owned.
+ CNATFWUNSAFMessage& iRequest;
+
+ // STUN server's address where the request is sent to
+ const TInetAddr& iAddress;
+
+ // Shared secret for calculating a hash
+ const TDesC8& iSharedSecret;
+
+ // Provides UDP sending services. Owned.
+ CNATFWUNSAFUdpSender* iSender;
+
+ // Provides sending services. Owned.
+ CNATFWUNSAFMediaConnSender* iMediaConSender;
+
+ // Amount of sent Binding Requests
+ TInt iSendCount;
+
+ // Initial retransmission interval, milliseconds
+ TInt iInitialRetransmitInterval;
+
+ // Current retransmission interval, milliseconds
+ TInt iRetransmitInterval;
+
+ // Public address received from a Binding Response's MAPPED-ADDRESS
+ // attribute
+ TInetAddr iMappedAddress;
+
+ // Public address received from a Binding Response's XOR-MAPPED-ADDRESS
+ // attribute
+ TInetAddr iXorMappedAddress;
+
+ // Public address received from a Binding Response's RELAY-ADDRESS
+ // attribute
+ TInetAddr iRelayAddress;
+
+ // UNKNOWN-ATTRIBUTES received from a 420 error response. Owned.
+ CNATFWUNSAFUnknownAttributesAttribute* iUnknownAttr;
+
+ // ETrue if the request should be retransmitted with specified interval.
+ // EFalse when retransmission must not be done any longer.
+ TBool iRetransmit;
+
+ // Has the transaction terminated
+ TBool iTerminated;
+
+ // Used natfw stream id
+ TUint iStreamId;
+
+ // Used natfw substream id
+ TUint iSubstreamId;
+
+ /**
+ * Used protocol, either "stun" or "stun-relay"
+ */
+ HBufC8* iProtocol;
+
+ /**
+ * Timer value from attribute
+ */
+ TUint32 iTimerValue;
+
+ /**
+ * Destination Address
+ */
+ TInetAddr iDestAddr;
+
+ /**
+ * Contains state information, e.g. request is pending --> ETrue
+ */
+ TBool iRequestPending;
+
+ /**
+ * Used transport protocol
+ */
+ TTransportProtocol iTransportProtocol;
+
+ /**
+ * Indicates hometime for last sent transaction.
+ */
+ TTime iSendTime;
+
+ /**
+ * This is compare value to find out is the request retransmitted.
+ * Default value is one.
+ */
+ TInt iRetransmitCompareValue;
+
+ /**
+ * ETrue if fingerprint will be added to transactions
+ */
+ TBool iUseFingerprint;
+
+ /**
+ * Disable resending packets in this transaction, only consume time
+ * while this flag is ETrue.
+ */
+ TBool iDisableSending;
+
+ private: // For testing purposes
+
+#ifdef TEST_EUNIT
+ friend class CSTUNClientTest;
+ friend class CSTUNBindingTest;
+ friend class CSTUNBindingImplementationTest;
+ friend class CSTUNTransactionTest;
+#endif
+ __DECLARE_TEST;
+ };
+
+#endif // C_CSTUNTRANSACTION_H