natfw/natfwstunturnclient/inc/cstunclientimplementation.h
changeset 0 1bce908db942
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/natfw/natfwstunturnclient/inc/cstunclientimplementation.h	Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,582 @@
+/*
+* Copyright (c) 2006-2007 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_STUNCLIENTIMPLEMENTATION_H
+#define C_STUNCLIENTIMPLEMENTATION_H
+
+// INCLUDES
+#include <e32base.h>
+#include <in_sock.h>
+#include "natfwunsafserverresolver.h"
+#include "natfwunsafserverresolverobserver.h"
+#include "mnatfwunsaficmperrorobserver.h"
+#include "msharedsecretobserver.h"
+#include "mstunbindingobserver.h"
+#include "cstuntimeruser.h"
+#include "natfwstunclientdefs.h"
+
+
+// FORWARD DECLARATIONS
+class CDeltaTimer;
+class CIcmpReceiver;
+class MSTUNClientObserver;
+class CSTUNClient;
+class CBinding;
+class CTransactionIDGenerator;
+class CSTUNSharedSecret;
+class CSTUNCredentials;
+class CSTUNClientState;
+class CSTUNClientResolvingTLS;
+class CSTUNClientResolvingTCP;
+class CSTUNClientResolvingUDP;
+class CSTUNClientGetSharedSecret;
+class CSTUNClientReady;
+class CSTUNClientRenewSharedSecret;
+class CAsyncCallback;
+class MNcmConnectionMultiplexer;
+
+
+// CLASS DECLARATION
+/**
+* This class hides the implementation STUN client from the user.
+* @lib natfwstunclient.lib
+*/
+class CSTUNClientImplementation :    
+    public CSTUNTimerUser,
+    public MNATFWUNSAFServerResolverObserver,
+    public MIcmpErrorObserver,
+    public MSharedSecretObserver,
+    public MSTUNBindingObserver
+    {
+    friend class ut_cstunrelaybindingimplementation;
+    friend class ut_cstunclientimplementation;
+    
+    public: // Constructors and destructor
+    
+        /**
+        * Creates a new instance of CSTUNClientImplementation.
+        * Starts the initialization procedures for STUN Client.
+        *     
+        * @param aClient STUN client
+        * @param aRetransmitInterval Retransmit interval for STUN binding
+        *         requests
+        * @param aServerAddress FQDN or IP address of the STUN or TURN 
+        *        server to be used.
+        * @param aServerPort if not zero, 
+        *        server port to be used instead of STUN or TURN default port 
+        * @param aServiceName Client must tell used servicename
+        *        ("stun" or "stun-relay") because of discovery of server
+        *        functionality
+        * @param aSocketServ A connected socket server session
+        * @param aConnection An active connection started by the client
+        *        with RConnection::Start()
+        * @param aTimer Timer services
+        * @param aObserver A callback for STUN Client event notifications
+        * @param aObtainSharedSecret If ETrue obtains a shared secret 
+        *        which will be used for the STUN Binding Requests.
+        *        If EFalse STUN Binding Requests will be sent without 
+        *        the shared secret related attributes.
+        * @param aFailIfNoSRVRecordsFound If ETrue, resolving fails if no SRV
+        *         records for STUN server were found.
+        * @param aIcmpReceiverUsed Desides whether icmp receiver is
+        *        instantiated in STUN client
+        * @param aMultiplexer instance of multiplexer.
+        * @param aTransportProtocol Used transport protocol.
+        *
+        * @return A new instance, ownership is transferred.
+        */
+        static CSTUNClientImplementation* NewL(            
+            CSTUNClient& aClient,
+            TInt aRetransmitInterval,            
+            const TDesC8& aServerAddress,
+            TUint aServerPort,
+            const TDesC8& aServiceName,
+            RSocketServ& aSocketServ,
+            RConnection& aConnection,
+            CDeltaTimer& aTimer,
+            MSTUNClientObserver& aObserver,
+            TBool aObtainSharedSecret,
+            TBool aFailIfNoSRVRecordsFound,
+            TBool aIcmpReceiverUsed,
+            MNcmConnectionMultiplexer* aMultiplexer,
+            TTransportProtocol aTransportProtocol );
+        
+        /**
+         * Creates a new instance of CSTUNClientImplementation (for 
+         * ICE connectivity checks).
+         * Starts the initialization procedures for STUN Client.
+         *     
+         * @param aClient STUN client
+         * @param aRetransmitInterval Retransmit interval for STUN binding
+         *        requests
+         * @param aTimer Timer services
+         * @param aObserver A callback for STUN Client event notifications
+         * @param aMultiplexer instance of multiplexer.
+         * @param aTransportProtocol Used transport protocol.
+         *
+         * @return A new instance, ownership is transferred.
+         */
+        static CSTUNClientImplementation* NewL(            
+            CSTUNClient& aClient,
+            TInt aRetransmitInterval,
+            CDeltaTimer& aTimer,          
+            MSTUNClientObserver& aObserver,
+            MNcmConnectionMultiplexer* aMultiplexer,
+            TTransportProtocol aTransportProtocol );
+            
+        /**
+         * Destructor.
+         */
+        ~CSTUNClientImplementation();
+
+    public: // From CSTUNTimerUser
+
+        void TimerExpiredL();
+
+        void LeaveFromTimerExpired( TInt aError );
+
+    public: // From MUNSAFServerResolverObserver
+    
+        void CompletedL();
+
+        void ErrorOccured( TInt aError );
+
+    public: // From MIcmpErrorObserver
+
+        void IcmpError( const TInetAddr& aAddress );
+
+    public: // From MSharedSecretObserver
+
+        void SharedSecretObtainedL();
+
+        void SharedSecretErrorL( TInt aError );
+
+    public: // From MSTUNBindingObserver
+
+        const CSTUNClient& STUNClient() const;
+
+        CDeltaTimer& TimerProvider();
+        
+        TInt RetransmitInterval() const;
+
+        TTransportProtocol TransportProtocol() const;
+        
+        void AddressResolvedL( const CBinding& aBinding ) const;
+
+        void ObtainSharedSecretL( CBinding& aBinding );
+
+        TBool SharedSecretRejectedL( const CBinding& aBinding,
+                                     const TDesC8& aUsername,
+                                     const TDesC8& aPassword );
+
+        TBool ObtainServerAddress( TInetAddr& aAddress );
+        
+        void ObtainTransactionIDL( TNATFWUNSAFTransactionID& aTransactionID );
+
+        void AttachBindingL( const CBinding& aBinding );
+
+        void DetachBinding( const CBinding& aBinding );
+        
+        void BindingErrorL( const CBinding& aBinding, TInt aError, 
+                            TBool aIsFatal );
+        
+        void BindingEventOccurred( const CBinding& aBinding, 
+                                   TSTUNCallbackInfo::TFunction aEvent );
+        
+        void RenewSharedSecretL();
+        
+        const TDesC8& UsernameForIndication();
+        
+        const TDesC8& PasswordForIndication();
+        
+
+    public: // New functions
+    
+        /**
+        * Check whether this STUN Client has been properly initialized
+        * and can be used to create STUN bindings.    
+        * @return ETrue if the client is initialized, otherwise EFalse
+        */
+        TBool IsInitialized() const;
+        
+        /**
+        * Gets the STUN server address and port used for this client when
+        * sending Binding Requests.
+        * @pre IsInitialized() == ETrue
+        * @return STUN server used to keep the NAT bindings alive
+        * @leave KErrNotReady if IsInitialized() == EFalse
+        * @leave KErrNotFound if STUN client has no responding addresses left
+        */
+        const TInetAddr& STUNServerAddrL() const;
+
+        /**
+        * Sets credentials for the STUN server used.
+        * These credentials override any existing ones and are used for all
+        * the binding requests.
+        * @pre aUsername's length must be larger than zero and a multiple of 4
+        * @pre aPasswd's length must be larger than zero and a multiple of 4
+        * @param aUsername username
+        * @param aPasswd password
+        */
+        void SetCredentialsL( const TDesC8& aUsername, 
+            const TDesC8& aPassword );
+
+        /**
+        * Tells if the Binding Requests will be sent protected with the
+        * MESSAGE-INTEGRITY attribute.
+        * @return ETrue if message integrity is used, EFalse otherwise
+        */
+        TBool SharedSecretObtained() const;
+
+        /**
+        * Returns information telling if application has set credentials.
+        * @return ETrue  Application has provided credentials
+        *          EFalse Otherwise
+        */
+        TBool HasPresetCredentials() const;
+
+        /**
+        * Change the object's state.        
+        * @param aNewState State to enter, can be NULL. Ownership is not
+        *    transferred.
+        */
+        void ChangeState( const CSTUNClientState* aNewState );
+
+        /**
+        * STUN client has encountered an error which it cannot ignore.
+        * Pass the error to NAT Traversal FW and enter "terminated" state.        
+        * @pre aError != KErrNone
+        * @param aError Reason for the failure
+        */
+        void Terminate( TInt aError );
+        
+        
+        /**
+         * TLS resolving has been done (either successfully or failing).
+         *
+         * @since   s60 v3.2
+         * @return  void        
+         */
+        void TlsResolvedL( );
+                
+        /**
+        * TCP resolving has been done (either successfully or failing).
+        * @param aObtainSharedSecret ETrue if shared secret should be obtained.        
+        *                             EFalse if shared secret will not be used.
+        */
+        void TcpResolvedL( TBool aObtainSharedSecret );
+
+        /**
+        * Release resources allocated for address resolving.        
+        */
+        void FreeResolverResources();
+        
+        /**
+        * Retrieve a shared secret from a STUN server, by sending a Shared
+        * Secret Request.
+        */
+        void GetSharedSecretFromServerL();
+        
+        /**
+        * Give the shared secret information the binding.
+        * @param aBinding STUN binding requesting a shared secret.
+        */
+        void PassSharedSecretToBindingL( CBinding& aBinding ) const;
+
+        /**
+        * Pass the shared secret to all bindings that are waiting it.        
+        */
+        void InformWaitingBindingsL() const;
+
+        /**
+        * Error occurred while trying to obtain a shared secret. In case of a
+        * connection failure or timeout, check if there are more TCP addresses
+        * left to try.
+        * @pre aError != KErrNone
+        * @param aError Reason for the failure        
+        */
+        void HandleSharedSecretErrorL( TInt aError );
+
+        /**
+        * Check if the username and password match the values in currently used
+        * shared secret.
+        * @param aUsername Username to compare
+         * @param aPassword Password to compare
+         * @return ETrue Values match, EFalse otherwise    
+        */
+        TBool DoesSharedSecretMatch( const TDesC8& aUsername,
+                                           const TDesC8& aPassword ) const;
+
+        /**
+        * Sends STUNClientInitCompleted event to upper layer, together with the
+        * aError status code.
+        * @param aError Initialization completion status
+        */
+        void PassInitCompletedL( TInt aError ) const;
+
+        /**
+        * Inform application that server rejected the provided credentials.
+        * @param aBinding STUN binding that used the credentials
+        */
+        void PassCredentialsRejectedL( const CBinding& aBinding ) const;
+
+        /**
+        * Start a timer to control when the shared secret expires.
+        */
+        void StartSharedSecretTimer();
+        
+        /**
+         * Multiplexer instance can be queried.
+         *
+         * @since   s60 v3.2
+         * @return  multiplexer instance
+         */
+        MNcmConnectionMultiplexer* MultiplexerInstance();
+        
+
+    private: // Enumerations
+    
+        enum TSTUNConstants
+            {
+            EDefaultSTUNPort = 3478
+            };
+
+    private: // Constructors
+    
+        CSTUNClientImplementation( CSTUNClient& aClient,
+                                   TInt aRetransmitInterval,
+                                   TUint aServerPort,
+                                   RSocketServ& aSocketServ,
+                                   RConnection& aConnection,
+                                   CDeltaTimer& aTimer,
+                                   MSTUNClientObserver& aObserver,
+                                   TBool aObtainSharedSecret,
+                                   MNcmConnectionMultiplexer* aMultiplexer,
+                                   TTransportProtocol aTransportProtocol );
+                                   
+        CSTUNClientImplementation( CSTUNClient& aClient,
+                                   TInt aRetransmitInterval,
+                                   CDeltaTimer& aTimer,
+                                   MSTUNClientObserver& aObserver,
+                                   MNcmConnectionMultiplexer* aMultiplexer,
+                                   TTransportProtocol aTransportProtocol );
+
+        CSTUNClientImplementation();
+        
+
+        CSTUNClientImplementation(
+            const CSTUNClientImplementation& aImplementation );
+
+        void ConstructL( const TDesC8& aServerAddress,
+                         const TDesC8& aServiceName,
+                         TBool aFailIfNoSRVRecordsFound,
+                         TBool aIcmpReceiverUsed );
+        
+        void ConstructL();
+        
+
+    private: // New functions, for internal use        
+
+        void ResolveAddressL( const TDesC8& aProtocol,
+                              RArray<TInetAddr>& aResult );
+        
+        void ResolveAddressL( const TDesC8& aProtocol,
+                              RArray<TInetAddr>& aResult,
+                              TUint aPort,
+                              const TDesC8& aServiceName );
+        
+
+        /**
+        * Obtain STUN server's UDP addresses.
+        */
+        void ResolveUdpL();
+
+        /**
+        * Removes the specified address from the list of STUN server's UDP
+        * addresses.
+        * @param aAddress Address to remove
+        */
+        void RemoveAddress( const TInetAddr& aAddress );
+
+    private: // Data
+
+        CSTUNClient& iClient;
+        
+        /**
+         * Retransmit interval
+         */
+        TInt iRetransmitInterval;
+        
+        /** 
+         * STUN or TURN server's port to use. After resolving, 
+         * the correct port to use is also in the TInetAddrs stored in 
+         * iTcpAddresses and iUdpAddresses.
+         */
+        TUint iServerPort;
+        
+        /**
+         * Reference to RSocketServ
+         */
+        RSocketServ& iSocketServer;
+        
+        /**
+         * Reference to RConnection
+         */
+        RConnection& iConnection;
+
+        /** 
+         * Callback to upper layer
+         * Not owned.
+         */
+        MSTUNClientObserver& iObserver;
+
+        /**
+         * If ETrue obtains a shared secret, which will be used for the STUN
+         * Binding Requests. If EFalse STUN Binding Requests will be sent without
+         * the shared secret related attributes.
+         */
+        TBool iObtainSharedSecret;
+        
+        /**
+         * Pointer to multiplexer
+         * Not own.
+         */ 
+        MNcmConnectionMultiplexer* iMultiplexer;
+
+        /**
+         * Callback dispatcher
+         * Own.
+         */
+        CAsyncCallback* iAsyncCallback;
+
+        /**
+         * STUN or TURN server address (FQDN or IP address).
+         * Exists only for the initialization phase.
+         * Own.
+         */
+        HBufC8* iServerAddress;
+
+        /**
+         * For resolving the STUN server address, owned.
+         * Exists only for the initialization phase.
+         * Own.
+         */
+        CNATFWUNSAFServerResolver* iResolver;
+
+
+        /** 
+         * The first address in the array is the currently used one. If it no
+         * longer responds, causing timeout, it will be removed from the array
+         * and the next address will be the one to use. When addresses run out,
+         * STUN client terminates and an error is reported to application.
+         */
+
+        /**
+         * Resolved STUN server TCP addresses.
+         */
+        RArray<TInetAddr> iTcpAddresses;
+
+        /**
+         * Resolved STUN server UDP addresses.
+         */
+        RArray<TInetAddr> iUdpAddresses;
+
+        /**
+         * Transaction id generator
+         * Own.
+         */
+        CTransactionIDGenerator* iTransactionIDGenerator;
+
+        /**
+         * Shared secret retriever. 
+         * Own.
+         */
+        CSTUNSharedSecret* iSharedSecret;
+        
+        /**
+         * Credentials set by application, can be NULL.
+         * Own.
+         */
+        CSTUNCredentials* iCredentials;
+
+        /**
+         * Bindings associated with this STUN client instance. The bindings are
+         * not owned by CSTUNClientImplementation.
+         */
+        RPointerArray<CBinding> iBindings;
+
+        /**
+         * icmp receiver
+         * Own.
+         */
+        CIcmpReceiver* iIcmpReceiver;
+
+        /**
+         * The current state of the CSTUNClientImplementation, not owned.
+         * If the pointer is NULL, it indicates the CSTUNClientImplementation
+         * has "terminated".
+         * Own.
+         */
+        const CSTUNClientState* iState;
+        
+        /**
+         * STUN client's states
+         * Own.
+         */
+        CSTUNClientResolvingTLS* iResolvingTLS;
+        CSTUNClientResolvingTCP* iResolvingTCP;
+        CSTUNClientResolvingUDP* iResolvingUDP;
+        CSTUNClientGetSharedSecret* iGetSharedSecret;
+        CSTUNClientReady* iReady;
+        CSTUNClientRenewSharedSecret* iRenewSharedSecret;
+        
+        /**
+         * Deltatimer, for shared timer services
+         * Own.
+         */
+        CDeltaTimer* iTimer;
+        
+        /**
+         * Service name contains NAT protocol, e.g. "STUN" or "STUN-RELAY"
+         * Own.
+         */
+        HBufC8* iServiceName;
+        
+        /**
+         * Transport protocol
+         */
+        TTransportProtocol iTransportProtocol;
+        
+
+    private: // For testing purposes
+
+#ifdef TEST_EUNIT
+        friend class CSTUNClientTest;
+        friend class CSTUNClientImplementationTest;
+        friend class CSTUNBindingTest;
+        friend class CAsyncCallbackTest;
+        friend class STUNTestUtils;
+#endif
+        __DECLARE_TEST;
+    };
+
+#endif // C_STUNCLIENTIMPLEMENTATION_H
+
+// End of File