networkprotocols/iphook/inhook6/include/flow.h
changeset 0 af10295192d8
child 5 1422c6cd3f0c
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // flow.h - IPv6/IPv4 flow information
       
    15 // IPv6/IPv4 flow information.
       
    16 //
       
    17 
       
    18 
       
    19 
       
    20 /**
       
    21  @file flow.h
       
    22  @publishedPartner
       
    23  @released
       
    24 */
       
    25 
       
    26 #ifndef __FLOW_H__
       
    27 #define __FLOW_H__
       
    28 
       
    29 #define SYMBIAN_NETWORKING_UPS
       
    30 
       
    31 #include <es_prot.h>
       
    32 #include <nifmbuf.h>
       
    33 #include "in_pkt.h"
       
    34 #include "apibase.h"
       
    35 
       
    36 //
       
    37 //	TFlowStatus
       
    38 //
       
    39 /**
       
    40 * Type of the flow status (some symbolic enum names).
       
    41 * @since v7.0
       
    42 * @publishedPartner
       
    43 * @released
       
    44 */
       
    45 enum TFlowStatus
       
    46 	{
       
    47 	/**
       
    48 	* (< 0) Flow is in error state.
       
    49 	*
       
    50 	* All other system wide error codes also indicate a flow error state. 
       
    51 	* To recover, the flow must be reconnected.
       
    52 	*/
       
    53 	EFlow_DOWN = KErrNotReady,
       
    54 	/**
       
    55 	* (= 0) Flow is ready to send data.
       
    56 	*/
       
    57 	EFlow_READY = 0,
       
    58 	/**
       
    59 	* (= 1) Flow is temporarily blocked.
       
    60 	*
       
    61 	* This is used when the flow is waiting for the connection setup. 
       
    62 	* When there is a possibility that flow could change into EFLow_READY
       
    63 	* state, the notifier is notified with MProviderNotify::CanSend().
       
    64 	*/
       
    65 	EFlow_PENDING = 1,
       
    66 	/**
       
    67 	* (= 2) Flow is temporarily blocked.
       
    68 	*
       
    69 	* This is used when the flow is blocked due to congestion (e.g. lower level 
       
    70 	* buffers are full). When congestion clears and if there is a possibility
       
    71 	* that flow could change into EFLow_READY state, the notifier is notified
       
    72 	* with MProviderNotify::CanSend().
       
    73 	*/
       
    74 	EFlow_HOLD = 2
       
    75 #ifdef SYMBIAN_TCPIPDHCP_UPDATE
       
    76 	,
       
    77     EFlow_NOTCONFIGURE = 3
       
    78 #endif //SYMBIAN_TCPIPDHCP_UPDATE    
       
    79 	};
       
    80 
       
    81 //	MProviderNotify
       
    82 //	***************
       
    83 class MProviderNotify : public MInetBase
       
    84 	/**
       
    85 	* Receiver of the notifications of the status changes in the flow.
       
    86 	*
       
    87 	* Note that the two functions CanSend() and Error() are a subset of MSocketNotify. This allows 
       
    88 	* a Service Access Point to implement the interface just by calling the equivalent 
       
    89 	* MSocketNotify functions. 
       
    90 	* @since v7.0
       
    91 	* @publishedPartner
       
    92 	* @released
       
    93 	*/
       
    94 	{
       
    95 public:
       
    96 	/**
       
    97 	* Flags that the flow might be ready to change into the EFlow_READY status
       
    98 	*
       
    99 	* The flow is (or has been) in EFlow_PENDING or EFlow_HOLD state. The flow
       
   100 	* owner can now check if flow really can be changed into EFlow_READY state.
       
   101 	* The state is updated by calling RFlowContext::Status (or some other functions
       
   102 	* that implicitly refresh the flow state by calling internally the
       
   103 	* CFlowContext::RefreshFlow function).
       
   104 	*
       
   105 	* Even if this function is called, the flow can still be in error or blocked
       
   106 	* state. This is because, for example, when congestion clears, all flows
       
   107 	* waiting for that event are notified, but some earlier notified flow may
       
   108 	* already have refilled all the buffers.
       
   109 	*/
       
   110 	virtual void CanSend() = 0;
       
   111 	/**
       
   112 	* The flow has entered an error state.
       
   113 	*
       
   114 	* Error state in a flow is permanent and requires a new connect (CFlowContext::Connect)
       
   115 	* to be cleared. A new connect occurs implicitly at FlowContext::Status (or some
       
   116 	* at some other functions), if flows connection parameters have been modified
       
   117 	* since the last connect (CFlowContext::iChanged is 1).
       
   118 	*
       
   119 	* @param aError Flow error code
       
   120 	* @param anOperationMask A bitmask of MSocketNotify::TOperationBitmasks values 
       
   121 	* specifying which pending operations are affected by the error up-call.
       
   122 	*/
       
   123 	virtual void Error(TInt aError, TUint anOperationMask=MSocketNotify::EErrorAllOperations) = 0;
       
   124 	virtual void NoBearer(const TDesC8& aConnectionParams) = 0;
       
   125 	virtual void Bearer(const TDesC8 &aConnectionInfo) = 0;
       
   126 	virtual TInt CheckPolicy(const TSecurityPolicy&, const char *) 
       
   127 		{
       
   128 		return KErrNone;
       
   129 		};
       
   130 	};
       
   131 
       
   132 
       
   133 //
       
   134 //	RFlowContext
       
   135 //	************
       
   136 //
       
   137 class MFlowManager;
       
   138 class CFlowContext;
       
   139 class CNifIfBase;
       
   140 
       
   141 //	*WARNING*:
       
   142 //		Because RFlowContext is used as a member of RMBufSendInfo, which may
       
   143 //		get moved around, the RFlowContext handle *MUST* not contain anything
       
   144 //		that breaks if it is copied bit-by-bit from one memory area to another!
       
   145 //		(for example don't even think of adding link fields and linking
       
   146 //		RFlowContext's into a list!) -- msa
       
   147 //
       
   148 class RFlowContext
       
   149 	/**
       
   150 	* A handle to a flow context.
       
   151 	*
       
   152 	* The main purpose of this class is to provide automatic reference counting 
       
   153 	* for flow context users.
       
   154 	*
       
   155 	* A typical use for a RFlowContext object is to:
       
   156 	* @li	allocate a context to a handle through the flow manager (Open())
       
   157 	* @li	set appropriate flow parameters (the upper layer protocol associated with 
       
   158 	* 		the flow, destination and source addresses)
       
   159 	* @li 	use the flow to send packets out
       
   160 	* @li 	release the context (Close()) from the handle. 
       
   161 	* @since v7.0
       
   162 	* @publishedPartner
       
   163 	* @released
       
   164 	*/
       
   165 	{
       
   166 public:
       
   167 	inline RFlowContext() : iFlow(0)
       
   168 		/**
       
   169 		* Default constructor.
       
   170 		*
       
   171 		* This creates a handle without any assigned flow context.
       
   172 		*/
       
   173 		{}
       
   174 	IMPORT_C TInt Open(MFlowManager *aManager, const TSockAddr &aDst, const TSockAddr &aSrc, TUint aProtocol = 0, TUint aIcmpType = 0, TUint aIcmpCode = 0);
       
   175 	IMPORT_C TInt Open(MFlowManager *aManager, TUint aProtocol = 0);
       
   176 	IMPORT_C TInt Open(RFlowContext &aContext, RMBufPktInfo *aInfo = NULL);
       
   177 	IMPORT_C TInt Clone(const RFlowContext &aFlow);
       
   178 	IMPORT_C TInt ReOpen();
       
   179 	IMPORT_C TInt Connect();
       
   180 
       
   181 	inline TBool IsOpen()
       
   182 		/**
       
   183 		* Tests if context is attached
       
   184 		*/
       
   185 		{return iFlow != NULL;}
       
   186 
       
   187 	IMPORT_C void SetRemoteAddr(const TSockAddr &aAddr);
       
   188 	IMPORT_C void SetLocalAddr(const TSockAddr &aAddr);
       
   189 	IMPORT_C void SetProtocol(TUint aProtocol);
       
   190 	IMPORT_C void SetIcmpType(TUint aType, TUint aCode = 0);
       
   191 	IMPORT_C MProviderNotify *SetNotify(MProviderNotify *aProvider);
       
   192 	IMPORT_C TInt Status();
       
   193 	IMPORT_C void Grab(RFlowContext &aContext);
       
   194 	IMPORT_C void Copy(RFlowContext &aContext);
       
   195 	IMPORT_C void Close();
       
   196 	IMPORT_C CNifIfBase *Interface() const;
       
   197 	
       
   198 #ifdef SYMBIAN_TCPIPDHCP_UPDATE
       
   199 	IMPORT_C TBool IsNdResolutionPending(); //RFC 4861 - Section 7.2.2
       
   200 #endif //SYMBIAN_TCPIPDHCP_UPDATE
       
   201 	inline CFlowContext *FlowContext() const
       
   202 		/** Gets a pointer to the flow context object (CFlowContext)
       
   203 		* attached to the handle.
       
   204 		*
       
   205 		* This can be used for more detailed control of the flow parameters.
       
   206 		*
       
   207 		* The returned pointer has limited validity,
       
   208 		* and it should not be stored in any members of permanent objects.
       
   209 		* In addition, care must be taken not to call any operation that could
       
   210 		* destroy the flow context as a side effect.
       
   211 		*
       
   212 		* If there is a need for longer validity of the retrieved pointer,
       
   213 		* the CFlowContext::Open and CFlowContext::Close methods can be used
       
   214 		* to protect it.
       
   215 		*
       
   216 		* @return
       
   217 		*		The flow context object.
       
   218 		*/
       
   219 		{ return iFlow; }
       
   220 private:
       
   221 	/** The flow context. */
       
   222 	CFlowContext *iFlow;
       
   223 	};
       
   224 
       
   225 
       
   226 
       
   227 //	******************************
       
   228 //	RMBufSendInfo, RMBufSendPacket
       
   229 //	******************************
       
   230 class RMBufSendInfo : public RMBufPktInfo
       
   231 	/**
       
   232 	* Information for outgoing packets.
       
   233 	*
       
   234 	* This extends the packet information class to record the flow context. 
       
   235 	* @since v7.0
       
   236 	* @publishedPartner
       
   237 	* @released
       
   238 	*/
       
   239 	{
       
   240 public:
       
   241 	/** Flow context for the packet. */
       
   242 	RFlowContext iFlow;	
       
   243 	};
       
   244 
       
   245 /** @since v5.0 */
       
   246 typedef class RMBufInfoPacketBase<RMBufSendInfo> RMBufSendPacket;
       
   247 
       
   248 // TFlowInfo
       
   249 // *********
       
   250 class TFlowInfo
       
   251 	/**
       
   252 	* Collects the information which defines a flow 
       
   253 	* (The Upper Layer Flow Information). This is a
       
   254 	* member of CFlowContext.
       
   255 	*
       
   256 	* @since v7.0s
       
   257 	*/
       
   258 	{
       
   259 public:
       
   260 	/**
       
   261 	* Current remote addess as set by upper layer.
       
   262 	*
       
   263 	* Must always be specified before a flow can be connecte or
       
   264 	* used for sending packets.
       
   265 	*
       
   266 	* See RFlowContext::SetRemoteAddr, CFlowContext::RemoteAddr
       
   267 	*/
       
   268 	TInetAddr iRemote;
       
   269 	/**
       
   270 	* Current local address (system or application selected).
       
   271 	*
       
   272 	* See RFlowContext::SetLocalAddr, CFlowContext::LocalAddr
       
   273 	*/
       
   274 	TInetAddr iLocal;
       
   275 	/**
       
   276 	* The protocol associated with the flow.
       
   277 	*
       
   278 	* See RFlowContext::SetProtocol, CFlowContext::Protocol
       
   279 	*/
       
   280 	TUint8 iProtocol;
       
   281 	/**
       
   282 	* ICMP type, when protocol is ICMP (or similar).
       
   283 	*
       
   284 	* See RFlowContext::SetIcmpType, CFlowContext::GetIcmpTypeCode
       
   285 	*/
       
   286 	TUint8 iIcmpType;
       
   287 	/**
       
   288 	* ICMP code, when protocol is ICMP (or similar).
       
   289 	*
       
   290 	* See RFlowContext::SetIcmpType, CFlowContext::GetIcmpTypeCode
       
   291 	*/
       
   292 	TUint8 iIcmpCode;
       
   293 	/**
       
   294 	* Set when upper layer set the local address.
       
   295 	*
       
   296 	* When set, the stack assumes the upper layer has specified
       
   297 	* the source address of the flow. When not set, the stack
       
   298 	* chooses the source address.
       
   299 	*
       
   300 	* This flag is cleared or set by the RFlowContext::SetLocalAddr().
       
   301 	* The flag is cleared when address is unspecified and set otherwise.
       
   302 	* Initial value is unset, if SetLocalAddr is never called.
       
   303 	*
       
   304 	* See also CFlowContext::IsLocalSet
       
   305 	*/
       
   306 	TUint iLocalSet:1;
       
   307 	/**
       
   308 	* Set when interface errors should not affect the flow.
       
   309 	*
       
   310 	* When an interface goes down (or reports an error), all flows
       
   311 	* that are currently connected (routed) to this interface, are
       
   312 	* also set into error error state (effectively, causing a
       
   313 	* socket error to the applications).
       
   314 	*
       
   315 	* When this flag is set, flow is not set to the error state. However,
       
   316 	* if interface is going down, the flow is put into hold/pending
       
   317 	* state (until another or same interface becomes again available).
       
   318 	*
       
   319 	* See also the socket option: #KSoNoInterfaceError
       
   320 	*/
       
   321 	TUint iNoInterfaceError:1;
       
   322 	/**
       
   323 	* Set when this flow should not try to bring up the interface.
       
   324 	*
       
   325 	* When a connect is attempted on a flow and it fails due to
       
   326 	* missing routes (no suitable interfaces up or configured yet), the
       
   327 	* stack signals the NIFMAN (NoBearer notify function).
       
   328 	*
       
   329 	* When this flag is set, NIFMAN is not notified and the flow is
       
   330 	* just placed into hold/pending state to wait for possible interface
       
   331 	* or route to appear.
       
   332 	*
       
   333 	* @note
       
   334 	*	NoBearer does not exisit in pre 7.0s systems. In such
       
   335 	*	systems the stack itself activates the "netdial process" in
       
   336 	*	this situation.
       
   337 	*/
       
   338 	TUint iNoInterfaceUp:1;
       
   339 	/**
       
   340 	* Set when flow is used for packet forwarding.
       
   341 	*
       
   342 	* This flag, when set, disables the source address checking.
       
   343 	* Normally the stack works in "strong model" and requires that
       
   344 	* a packet has a valid source address on the interface.
       
   345 	* Forwarded packets have other than local source address and
       
   346 	* the check must be disabled.
       
   347 	*
       
   348 	* This can only be set internally or from the hooks. There is no
       
   349 	* application level socket option to set this.
       
   350 	*/
       
   351 	TUint iForwardingFlow:1;
       
   352 	// Note! Cannot use TScopeType below, because it would make the
       
   353 	// bitfield into signed and fail on tests like:
       
   354 	//		x.iLockType == EScopeType_NET
       
   355 	// even if x.iLockType has value EScopeType_NET!!! -- msa
       
   356 	/**
       
   357 	* Locked scope-1 (0..15) [TScopeType].
       
   358 	*
       
   359 	* This valid only when iLockId is non-zero.
       
   360 	*/
       
   361 	TUint iLockType:4;
       
   362 	/**
       
   363 	* Current Locking Id.
       
   364 	*
       
   365 	* Value ZERO is unlocked. Non-Zero value is a zone id in the scope
       
   366 	* specified by iLockType.
       
   367 	*/
       
   368 	TUint32 iLockId;
       
   369 	};
       
   370 
       
   371 
       
   372 //	************
       
   373 //	CFlowContext
       
   374 //	************
       
   375 //	A base class of the Flow Context, cannot be instantiated as is
       
   376 //
       
   377 class COptionValue;
       
   378 class MFlowHook;
       
   379 class MInterfaceManager;
       
   380 
       
   381 class CFlowContext : public CBase
       
   382 	/**
       
   383 	* The flow context instance.
       
   384 	*
       
   385 	* The CFlowContext has several public methods, but not all of them are safe
       
   386 	* (or even legal) to use in all situations.
       
   387 	*
       
   388 	* CFlowContext is a reference counted object. Whenever a pointer is
       
   389 	* stored for long term duration, the Open() must be called, and when
       
   390 	* pointer is no more used, a close must be called. This object is only
       
   391 	* deleted indirectly via use of Close(). The delete operator is never
       
   392 	* used explicitly from outside.
       
   393 	*
       
   394 	* Base class for a flow context.
       
   395 	* @since v7.0
       
   396 	* @publishedPartner
       
   397 	* @released
       
   398 	*/
       
   399 	{
       
   400 	friend class MFlowManager;
       
   401 	friend class RFlowContext;
       
   402 protected:
       
   403  	IMPORT_C CFlowContext(const void *aOwner, MFlowManager *aManager);
       
   404  	IMPORT_C CFlowContext(const void *aOwner, MFlowManager *aManager, CFlowContext &aFlow);
       
   405 	// Destructor should not be exported, it should be private! -- msa
       
   406 	IMPORT_C virtual ~CFlowContext();
       
   407 
       
   408 #ifdef SYMBIAN_NETWORKING_UPS
       
   409 	/**
       
   410 	Indicate whether the flow has a provider above it.
       
   411 	@return ETrue if it has, else EFalse.
       
   412 	*/
       
   413 	inline TBool HasProvider() const;
       
   414 	
       
   415 	
       
   416 	inline void *GetProviderApiL(const TDesC8& aApiName, TUint* aVersion);
       
   417 #endif //SYMBIAN_NETWORKING_UPS
       
   418 
       
   419 public:
       
   420 	IMPORT_C void Close();
       
   421 
       
   422 	inline void Open()
       
   423 		/**
       
   424 		* Increments a reference count on the context
       
   425 		*/
       
   426 		{ iRefs++; }
       
   427 	IMPORT_C TInt Status();
       
   428 	IMPORT_C void SetStatus(TInt aStatus);
       
   429 	IMPORT_C TInt StoreOption(TUint aLevel, TUint aName, const TDesC8 &aOption);
       
   430 	IMPORT_C TInt RetrieveOption(TUint aLevel, TUint aName, TDes8 &aOption) const;
       
   431 
       
   432 	inline TPacketHead &Head()
       
   433 		/**
       
   434 		* Gets access to precomputed information for the outbound packet flow.
       
   435 		*
       
   436 		* @return Precomputed information for the outbound packet flow
       
   437 		*/
       
   438 		{ return iHead; }
       
   439 
       
   440 	/**
       
   441 	* @defgroup	getselectors	Retrieve current selector fields
       
   442 	*
       
   443 	* @{
       
   444 	*/
       
   445 
       
   446  	inline TUint LocalPort() const
       
   447 		/**
       
   448 		* Gets the flow's local port.
       
   449 		* @return current local port
       
   450 		*/
       
   451 		{ return iInfo.iLocal.Port(); }
       
   452 
       
   453 	inline TUint RemotePort() const
       
   454 		/**
       
   455 		* Gets the flow's remote port.
       
   456 		* @return current remote port
       
   457 		*/
       
   458 		{ return iInfo.iRemote.Port(); }
       
   459 
       
   460 	inline TUint Protocol() const
       
   461 		/**
       
   462 		* Gets the flow protocol.
       
   463 		* @return current protocol
       
   464 		*/
       
   465 		{ return iInfo.iProtocol; }
       
   466 
       
   467 	inline const TInetAddr &LocalAddr() const
       
   468 		/**
       
   469 		* Gets the flow's local address.
       
   470 		*
       
   471 		* The local address may have been selected by the system, if
       
   472 		* the transport layer didn't set it (left it unspecified or
       
   473 		* explicitly set unspecified address to it).
       
   474 		*
       
   475 		* @note
       
   476 		*	All addresses in the flow context are kept in IPv6 format
       
   477 		*	(using IPv4 mapped addresses for IPv4 flows).
       
   478 		*
       
   479 		* @return Local address.
       
   480 		*/
       
   481 		{ return iInfo.iLocal; }
       
   482 
       
   483 	inline TBool IsLocalSet() const
       
   484 		/**
       
   485 		* Gets the flow's local address status.
       
   486 		*
       
   487 		* The local address can be selected by the stack, or application
       
   488 		* can have set it into a specific value. When this address status
       
   489 		* have value ETrue, the stack assumes that the local address has
       
   490 		* been chosen by the application or upper layer protocol. When
       
   491 		* status is EFalse, the stack selects the source
       
   492 		* address for the flow when the flow is connected
       
   493 		* (CFlowContext::Connect).
       
   494 		*
       
   495 		* The RFlowContext::SetLocalAddress will set this status to EFalse,
       
   496 		* if the address is unspecified address, and to ETrue otherwise.
       
   497 		*
       
   498 		* @note
       
   499 		*	If an application requires using the unspecified source address
       
   500 		*	in packets (IPv4 <tt>0.0.0.0</tt> or IPv6 <tt>::</tt>), it must use
       
   501 		*	the socket option #KSoNoSourceAddressSelect (level #KSolInetIp)
       
   502 		*	<em>after</em> it has performed the RSocket::Bind() to uspecified
       
   503 		*	address.
       
   504 		*
       
   505 		* Some upper layer protocols may also set this status, after the
       
   506 		* connection is established (TCP).
       
   507 		*
       
   508 		* @return ETrue, if local addr is set
       
   509 	 	*/
       
   510 		{ return iInfo.iLocalSet != 0; }
       
   511 
       
   512 	inline const TInetAddr &RemoteAddr() const
       
   513 		/**
       
   514 		* Gets the flow's remote address.
       
   515 		*
       
   516 		* @return Remote address.
       
   517 		*/
       
   518 		{ return iInfo.iRemote; }
       
   519 		
       
   520 	inline void GetIcmpTypeCode(TUint8 &aType, TUint8 &aCode) const
       
   521 		/**
       
   522 		* Gets the flow's ICMP type and code.
       
   523 		*
       
   524 		* @retval aType	Icmp (or other) type
       
   525 		* @retval aCode	Icmp (or other) code
       
   526 		*/
       
   527 		{ aType = iInfo.iIcmpType; aCode = iInfo.iIcmpCode; }
       
   528 
       
   529 	inline TScopeType LockType() const
       
   530 		/**
       
   531 		* Gets the flow's locking type [0..15].
       
   532 		*
       
   533 		* The locking type tells the type of the lock id. The type has no
       
   534 		* meaning if the lock id has zero value (= flow is not locked)..
       
   535 		*
       
   536 		* @return current type of LockId (IF=0, IAP=1, NET=15).
       
   537 		*/
       
   538 		{ return (TScopeType)iInfo.iLockType; }
       
   539 
       
   540 	inline TUint32 LockId() const
       
   541 		/**
       
   542 		* Gets the flows lock id.
       
   543 		*
       
   544 		* A flow can be locked to a specified scope. When locked (non-zero),
       
   545 		* the flow can only be connected to an interface within the locked
       
   546 		* scope.
       
   547 		*
       
   548 		* The id value is a plain 32 bit number and the domain of this
       
   549 		* value is defined by the locking type (CFlowContext::LockType).
       
   550 		*
       
   551 		* @return current lock id (IAP, NET or IF). Not locked, if ZERO
       
   552 		*/
       
   553 		{ return iInfo.iLockId; }
       
   554 
       
   555 	/** @} */
       
   556 
       
   557 	/**
       
   558 	* @defgroup packetsize	Accessing parameters of the packet size
       
   559 	*
       
   560 	* In all, return
       
   561 	*	@li	< 0, indicates an error or value not known
       
   562 	*	@li	= 0, (interpretation not fixed)
       
   563 	*	@li	> 0, the indicated value
       
   564 	*
       
   565 	* Some assertations that should be true
       
   566 	*	@li	PathMtu() > HeaderSize()
       
   567 	*	@li	HeaderSize() >= sizeof(TInet6HeaderIP)
       
   568 	*	@li	InterfaceSMtu() >= PathMTU()
       
   569 	*	@li	InterfaceRMtu() > sizeof(TInet6HeaderIP)
       
   570 	*
       
   571 	* @{
       
   572 	*/
       
   573 
       
   574 	inline TInt PathMtu() const
       
   575 		/**
       
   576 		* Gets the Path MTU of the flow.
       
   577 		*
       
   578 		* @return
       
   579 		* @li	< 0,    indicates an error or value not yet known (for example,
       
   580 		*				if accessed before the flow is connected or interface is up)
       
   581 		* @li	= 0,    value not known
       
   582 		*
       
   583 		* @li	> 0,     a real value
       
   584 		*/
       
   585 		{ return iPathMtu; }
       
   586 
       
   587 	inline TInt HeaderSize() const
       
   588 		/**
       
   589 		* Gets the amount of the protocol overhead in the packet from all of the lower layers.
       
   590 		*
       
   591 		* The value is defined only for a flow that has been connected.
       
   592 		* (CFlowContext::Connect).
       
   593 		*
       
   594 		* HeaderSize () > 0 (at least IPv4 or IPv6 header size)
       
   595 		*
       
   596 		* @return
       
   597 		* @li	< 0,    indicates an error or value not yet known (for example,
       
   598 		*				if accessed before the flow is connected or interface is up)
       
   599 		* @li	= 0,    value not known
       
   600 		* @li	> 0,	a real value
       
   601 		*/
       
   602 		{ return iHdrSize; }
       
   603 	
       
   604 	/**
       
   605 	* Gets the raw send MTU of the attached interface.
       
   606 	*
       
   607 	* The value is defined only for a flow that has been connected.
       
   608 	* (CFlowContext::Connect).
       
   609 	*
       
   610 	* @return
       
   611 	* @li	< 0,    indicates an error or value not yet known (for example,
       
   612 	*				if accessed before the flow is connected or interface is up)
       
   613 	* @li	= 0,    value not known
       
   614 	* @li	> 0,	a real value
       
   615 	*/
       
   616 	virtual TInt InterfaceSMtu() const = 0;
       
   617 	/**
       
   618 	* Gets the raw receive MTU of the interface.
       
   619 	*
       
   620 	* The value is defined only for a flow that has been connected.
       
   621 	* (CFlowContext::Connect).
       
   622 	*
       
   623 	* @return
       
   624 	* @li	< 0,    indicates an error or value not yet known (for example,
       
   625 	*				if accessed before the flow is connected or interface is up)
       
   626 	* @li	= 0,    value not known
       
   627 	* @li	> 0,	a real value
       
   628 	*/
       
   629 	virtual TInt InterfaceRMtu() const = 0;
       
   630 	/** @} */
       
   631 
       
   632 	/**
       
   633 	* Gets an option from the flow context.
       
   634 	*
       
   635 	* A set of options can be read from the flow context.
       
   636 	*
       
   637 	* In addition to internally supported options,
       
   638 	* any registered outbound hook can add support for additional options
       
   639 	* (see MIp6Hook::GetFlowOption documentation).
       
   640 	*
       
   641 	* The function is called part of the normal option processing.
       
   642 	*
       
   643 	* @param aLevel The option level
       
   644 	* @param aName The option name
       
   645 	* @param aOption The option value
       
   646 	* @return
       
   647 	*		KErrNone, or KErrNotSuppoted if option cannot be read from the flow context.
       
   648 	*/
       
   649 	virtual TInt GetOption(TUint aLevel, TUint aName, TDes8 &aOption) const = 0;
       
   650 
       
   651 	/**
       
   652 	* Sets an option to the flow context.
       
   653 	*
       
   654 	* A set of options can be set to the flow context.
       
   655 	*.
       
   656 	* In addition to internally supported options,
       
   657 	* any registered outbound hook can add support for additional options
       
   658 	* (see MIp6Hook::SetFlowOption documentation).
       
   659 	*
       
   660 	* The function is called part of the normal option processing.
       
   661 	*
       
   662 	* @param aLevel The option level
       
   663 	* @param aName The option name
       
   664 	* @param aOption The option value
       
   665 	* @return
       
   666 	*		KErrNone, or KErrNotSuppoted if option cannot be set from the flow context.
       
   667 	*/
       
   668 	virtual TInt SetOption(TUint aLevel, TUint aName, const TDesC8 &aOption) = 0;
       
   669 
       
   670 	/**
       
   671 	* Gets the currently connected interface.
       
   672 	*
       
   673 	* @return
       
   674 	*		The currently connected interface,
       
   675 	*		if the flow is properly connected, otherwise NULL.
       
   676 	*		The returned pointer has limited validity, and it should not be stored
       
   677 	*		in any members of permanent objects.
       
   678 	*/
       
   679 	virtual CNifIfBase *Interface() const = 0;
       
   680 
       
   681 	/**
       
   682 	* Gets the interface manager of the TCP/IP stack..
       
   683 	*
       
   684 	* @return
       
   685 	*		The interface manager.
       
   686 	*/
       
   687 	virtual MInterfaceManager *Interfacer() const = 0;
       
   688 
       
   689 	/**
       
   690 	* Sends a packet to the attached interface.
       
   691 	*
       
   692 	* This is a low level function intended for the IP layer itself.
       
   693 	* Send bypasses all the installed hooks and path mtu processing.
       
   694 	* The raw data in the packet is passed to the interface as is.
       
   695 	* (for the normal way of sending a packet, see MNetworkService::Send).
       
   696 	*
       
   697 	* If the flow is not connected, the Send drops the packet and the
       
   698 	* return is KErrNotReady.
       
   699 	*
       
   700 	* The destination address of the information block may get changed
       
   701 	* into link layer destination address, if the stack is handling the
       
   702 	* neighbour discovery on the link (ARP for IPv4, ICMPv6 Neighbor
       
   703 	* discovery for IPv6).
       
   704 	*
       
   705 	* If the destination is a multicast address, and if that address
       
   706 	* is also joined by some application(s), then a copy of the packet
       
   707 	* is sent to the inbound direction (MNetworkService::Process),
       
   708 	* unless disabled by #KSoIp6MulticastLoop socket option.
       
   709 	*
       
   710 	* @param aPacket
       
   711 	*		The data packet (assumed to be RMBufInfoPktBase in "packed" state)
       
   712 	* @param aSource
       
   713 	*		The source protocol instance (passed as is to the interface). Optional,
       
   714 	*		and usually NULL.
       
   715 	* @return
       
   716 	*		is defined similarly as the equivalent methods of the interfaces and
       
   717 	*		protocols, as follows:
       
   718 	* @li	< 0,
       
   719 	*		an error: the packet is not sent, but is dropped by Send().
       
   720 	* @li	= 0,
       
   721 	*		indicates that the interface received the packet, but is also signaling
       
   722 	*		that its reluctance to receive more packets. All flows attached to this
       
   723 	*		interface are automatically set into EFlow_HOLD state.
       
   724 	* @li	> 0,
       
   725 	*		indicates that the interface received the packet and is willing to
       
   726 	*		receive more after this.
       
   727 	*/
       
   728 	virtual TInt Send(RMBufChain &aPacket, CProtocolBase* aSource = NULL) = 0;
       
   729 
       
   730 	/** Attaches a flow to a route and an interface. */
       
   731 	virtual void Connect() = 0;
       
   732 	/** Disconnects the flow, and remove all hooks. */
       
   733 	virtual void Disconnect() = 0;
       
   734 	/** Recomputes the current flow status. */
       
   735 	virtual void RefreshFlow() = 0;
       
   736 	/**
       
   737 	* Sets "changed" state to flow(s).
       
   738 	*
       
   739 	* Sets the iChanged flag that indicates that connect information has changed.
       
   740 	* 
       
   741 	* When any component of the system determines that a flow or set
       
   742 	* of flows require an open phase (reconnect), the component can use the
       
   743 	* this function to force a reconnect of the flow on the next outgoing packet.
       
   744 	*
       
   745 	* @param aScope determines what flows are affected:
       
   746 	* @li	0: set iChanged on current flow
       
   747 	* @li	1: set iChanged on all flows with same route entry,
       
   748 	* @li	2: set iChanged on all flows with same interface,
       
   749 	* @li	> 2: set iChanged on all existing flows
       
   750 	*
       
   751 	* @return
       
   752 	*		Number of flows affected (regardless of their previous iChanged state)
       
   753 	*/
       
   754 	virtual TInt SetChanged(const TInt aScope = 0) = 0;
       
   755 #ifdef SYMBIAN_TCPIPDHCP_UPDATE
       
   756 	/* RFC 4861: Sec 7.2.2 Verifies any pending ND packets exists on a route during ND
       
   757 	 */
       
   758 	virtual TBool IsNdPacketPendingResolution() {return EFalse; } ; // Base implementation
       
   759 #endif //SYMBIAN_TCPIPDHCP_UPDATE
       
   760 	inline void NoBearer(const TDesC8& aConnectionParams);
       
   761 	inline void Bearer(const TDesC8 &aConnectionInfo);
       
   762 	inline TInt CheckPolicy(const TSecurityPolicy& aPolicy, const char *aDiagnostic);
       
   763 
       
   764 protected:
       
   765 	/** The owner of the flow (untyped ID data). */
       
   766 	const void *const iOwner;
       
   767 	/** The flow manager that created this object. */
       
   768 	MFlowManager *const iMgr;
       
   769 
       
   770 	/** Contains the object reference count.
       
   771 	* 
       
   772 	* For a single reference, this is 0.
       
   773 	*/
       
   774 	TInt iRefs;
       
   775 	/** The flow's status.
       
   776 	* 
       
   777 	* @li = 0: up and running
       
   778 	* @li > 0: pending
       
   779 	* @li < 0: error.
       
   780 	*/
       
   781 	TInt iStatus;
       
   782 public:	
       
   783 	/** The Upper Layer Flow Information */
       
   784 	TFlowInfo iInfo;
       
   785 protected:
       
   786 	/**	
       
   787 	* Set when flow needs a reconnect (selector information changed).
       
   788 	*
       
   789 	* When this is set (1), RFlowContext::Status (and some other methods) will
       
   790 	* automaticly call CFlowContext::Connect for the flow. Primary reason for
       
   791 	* this to be set is that the flow selector information has been changed
       
   792 	* (@ref setselectors).
       
   793 	*
       
   794 	* This can be set explicitly by the CFlowContext::SetChanged function (or
       
   795 	* MFlowManager::SetChanged).
       
   796 	*/
       
   797 	TUint iChanged:1;
       
   798 public:
       
   799 	/**
       
   800 	* Flag that indicates that NIF HOLD return should not block the flow.
       
   801 	*
       
   802 	* After a packet send a NIF can return a value that indicates that no
       
   803 	* more packets are to be sent to it, until it allows it again via
       
   804 	* the CProtocolBase::StartSending call. Normally, such indication
       
   805 	* sets the flow into HOLD state.
       
   806 	*
       
   807 	* When this flag is set, flow is not put into HOLD. This flag should
       
   808 	* only be used by a hook that have other means of enforcing the flow
       
   809 	* control (for example QOS).
       
   810 	*/
       
   811 	TUint iIgnoreFlowControl:1;
       
   812 	/** Precomputed packet header information. */
       
   813 	TPacketHead iHead;
       
   814 	/**
       
   815 	* The current Path MTU
       
   816 	*
       
   817 	* Set from the path MTU of the connected interface. May change
       
   818 	* dynamically due to ICMP "packet too big" or other events.
       
   819 	*/
       
   820 	TUint iPathMtu;
       
   821 	/**
       
   822 	* The header overhead by IP layer and hooks
       
   823 	*
       
   824 	* The iHdrSize is initialized to 0 at the beginning of the MIp6Hook::OpenL
       
   825 	* phase.
       
   826 	* The final value at the end of the OpenL phase is saved, and this value
       
   827 	* will be the initial value at the beginning of the MFlowHook::ReadyL phase.
       
   828 	*
       
   829 	* The final value at the end of the ReadyL phase must be the total amount
       
   830 	* of header space required by the layers below the transport (upper layer
       
   831 	* protocol). The space available for the upper layer header and payload
       
   832 	* is: iPathMtu - iHdrSize.
       
   833 	*
       
   834 	* The hook can add the header space requirement in OpenL or ReadyL
       
   835 	* method. If it does it in OpenL, it does not need to touch the
       
   836 	* iHdrSize in ReadyL method (for example, IPSEC only knows the
       
   837 	* exact required header space at ReadyL phase).
       
   838 	*
       
   839 	* If a hook uses the TPacketHead::iPacket member to store precomputed
       
   840 	* headers, which are automaticly appended to each packet, it must include
       
   841 	* the amount into iHdrSize (it must carefully compute the change of length
       
   842 	* in iPacket, if it adds new data there).
       
   843 	*
       
   844 	* The stack includes implicitly the header space for INNERMOST IP header
       
   845 	* (which is also the final IP header, if no tunneling is present). Any hook,
       
   846 	* that does tunneling, must include the OUTER IP header requirements into
       
   847 	* the iHdrSize (a tunneling hook is ADDING the outer header!).
       
   848 	*/
       
   849 	TUint iHdrSize;
       
   850 private:
       
   851 	/** Receives state change upcalls. Also the owner of the flow. */
       
   852 	MProviderNotify *iProvider;
       
   853 	/** Storage for any other options. */
       
   854 	COptionValue *iStorage;
       
   855 	};
       
   856 
       
   857 
       
   858 inline void CFlowContext::NoBearer(const TDesC8& aConnectionParams)
       
   859 	/** Passes NoBearer call to owner, if present. */
       
   860 	{
       
   861 	if (iProvider)
       
   862 		iProvider->NoBearer(aConnectionParams);
       
   863 	}
       
   864 inline void CFlowContext::Bearer(const TDesC8 &aConnectionInfo)
       
   865 	/** Passes Bearer call to owner, if present. */
       
   866 	{
       
   867 	if (iProvider)
       
   868 		iProvider->Bearer(aConnectionInfo);
       
   869 	}
       
   870 
       
   871 inline TInt CFlowContext::CheckPolicy(const TSecurityPolicy& aPolicy, const char *aDiagnostic)
       
   872 	{
       
   873 	return iProvider ? iProvider->CheckPolicy(aPolicy, aDiagnostic) : KErrNone;
       
   874 	}
       
   875 
       
   876 #ifdef SYMBIAN_NETWORKING_UPS
       
   877 inline TBool CFlowContext::HasProvider() const
       
   878 	{
       
   879 	return (iProvider != NULL);
       
   880 	}
       
   881 	
       
   882 inline void *CFlowContext::GetProviderApiL(const TDesC8& aApiName, TUint* aVersion)
       
   883 	{
       
   884 	if (iProvider == NULL)
       
   885 		{
       
   886 		return NULL;
       
   887 		}
       
   888 	else
       
   889 		{
       
   890 		return iProvider->GetApiL(aApiName, aVersion);		
       
   891 		}	
       
   892 	}
       
   893 	
       
   894 #endif //SYMBIAN_NETWORKING_UPS
       
   895 
       
   896 //	*********
       
   897 //	MFlowHook
       
   898 //	*********
       
   899 class MFlowHook : public MInetBase
       
   900 	/**
       
   901 	* Abstract base class for flow hooks.
       
   902 	*
       
   903 	* Flow hook providers implement this class. They register the hook using
       
   904 	* MIp6Hook::BindFlowHook(), and return an instance from MIp6Hook::OpenL().
       
   905 	*
       
   906 	* @note
       
   907 	*	The same instance of MFlowHook can be returned for multiple flows,
       
   908 	*	if the logic of the hook does not require unique instance for each flow.
       
   909 	*
       
   910 	* The object can be implemented as reference counted object: last reference
       
   911 	* removed by Close deletes the object.
       
   912 	*
       
   913 	* @since v7.0
       
   914 	* @publishedPartner
       
   915 	* @released
       
   916 	*
       
   917 	* Example:
       
   918 	* @dontinclude mflowhook.cpp
       
   919 	* @skip MFlowHook
       
   920 	* @until //-
       
   921 	*/
       
   922 	{
       
   923 public:
       
   924 	/**
       
   925 	* Increment reference count.
       
   926 	*
       
   927 	* The Open and Close functions must implement a reference
       
   928 	* counting system. The Close function must destroy the current
       
   929 	* instance, when the last reference is removed.
       
   930 	*
       
   931 	* Non-NULL return from MIp6Hook::OpenL() counts as one reference, and
       
   932 	* the stack is guaranteed to call the matching Close exactly once.
       
   933 	*
       
   934 	* If a hook creates a new instance for each flow at OpenL, it can
       
   935 	* leave the reference count as initial ZERO, if it implements a
       
   936 	* Close, which deletes the object when the count goes negative.
       
   937 	*
       
   938 	* If a hook returns an existing instance at OpenL, it must
       
   939 	* increment the reference count by one.
       
   940 	*
       
   941 	* Example:
       
   942 	* @dontinclude mflowhook.cpp
       
   943 	* @skip ::Open(
       
   944 	* @until //-
       
   945 	*/
       
   946 	virtual void Open() = 0;
       
   947 	/**
       
   948 	* On an interface connecting, asks the hook if a flow is ready.
       
   949 	*
       
   950 	* The ReadyL calls propagate interface ready state up the
       
   951 	* flow. The calls to hooks are made in reverse order;
       
   952 	* the closest to interface is called first. The call informs
       
   953 	* this hook that everything is ready from this hook to the interface.
       
   954 	* Now it this hooks turn to check the ready state of the flow.
       
   955 	*
       
   956 	* @param aHead
       
   957 	*		Address information of the flow.
       
   958 	* @return
       
   959 	*		from the ReadyL is the new status of the flow and has the following
       
   960 	*		implications
       
   961 	* @li	== 0, hook is ready, proceed to the next one or mark the flow
       
   962 	*		as READY, if this was the first hook.
       
   963 	* @li	> 0, hook is not ready, the ready calling is stopped and the
       
   964 	*		returned value is the (pending) state of the flow.
       
   965 	*		The hook MUST send a signal later to release this state to
       
   966 	*		reactivate the ReadyL call chain.
       
   967 	* @li	< 0, hook detected an unrecoverable error on flow
       
   968 	*
       
   969 	* @exception
       
   970 	*		If the ReadyL leaves, the leave status will become
       
   971 	*		the flow status  (the leave status must be negative, or KErrGeneral
       
   972 	*		is substituted for it)
       
   973 	*
       
   974 	* Example:
       
   975 	* @dontinclude mflowhook.cpp
       
   976 	* @skip ::ReadyL(
       
   977 	* @until //-
       
   978 	*/
       
   979 	virtual TInt ReadyL(TPacketHead &aHead) = 0;
       
   980 	/**
       
   981 	* Apply send transformations.
       
   982 	*
       
   983 	* The ApplyL is called by IP protocol  for outbound packet. The aPacket
       
   984 	* is in "unpacked" state (RMBufPacketBase::Unpack).
       
   985 	*
       
   986 	* @param aPacket
       
   987 	*		a complete packet to be processed (if needed) by the hook.
       
   988 	*		The packet includes the IP header.
       
   989 	* @param aInfo
       
   990 	*		information block associated with the packet (a hook must not
       
   991 	*		break this association!)
       
   992 	* @return
       
   993 	* @li	= 0,    (KErrNone) hook processed the packet, proceed with the next.
       
   994 	* @li	< 0,    (error code) hook discarded the packet for some reason, send is
       
   995 	*				aborted.
       
   996 	* @li	> 0,    restart hook processing [the actual utility of this is
       
   997 	*				still under consideration, maybe removed if no sensible
       
   998 	*				use found.]
       
   999 	*
       
  1000 	* @exception
       
  1001 	*		if ApplyL leaves, the packet is dropped.
       
  1002 	*
       
  1003 	* Example:
       
  1004 	* @dontinclude mflowhook.cpp
       
  1005 	* @skip ::ApplyL(
       
  1006 	* @until //-
       
  1007 	*/
       
  1008 	virtual TInt ApplyL(RMBufSendPacket &aPacket, RMBufSendInfo &aInfo) = 0;
       
  1009 	/**
       
  1010 	* Decrement references and destroy if last.
       
  1011 	*
       
  1012 	* Example:
       
  1013 	* @dontinclude mflowhook.cpp
       
  1014 	* @skip ::Close(
       
  1015 	* @until //-
       
  1016 	*/
       
  1017 	virtual void Close() = 0;
       
  1018 	};
       
  1019 
       
  1020 class CFlowInternalContext;
       
  1021 
       
  1022 class MFlowManager : public MInetBase
       
  1023 	/**
       
  1024 	* The flow manager interface.
       
  1025 	*
       
  1026 	* The use of MFlowManager is mostly hidden behind the RFlowContext,
       
  1027 	* but the upper layer must be aware of its existence.
       
  1028 	* Currently, the MFlowManager interface is included into the MnetworkService
       
  1029 	* (and is implemented by the IP6 protocol instance),
       
  1030 	* which must be used whenever an instance of MFlowManager is required.
       
  1031 	* @since v7.0
       
  1032 	* @publishedPartner
       
  1033 	* @released
       
  1034 	*/
       
  1035 	{
       
  1036 public:
       
  1037 	/**
       
  1038 	* Increase the "users" counter.
       
  1039 	*
       
  1040 	* The count of current "users" is used in determining whether to
       
  1041 	* keep or release resources. This in turn, may cause the disconnect
       
  1042 	* of a data connection.
       
  1043 	*
       
  1044 	* The stack leaves it up to the upper layers to decide what is counted as a 
       
  1045 	* "user". IncUsers() and DecUsers() should be used to give this information 
       
  1046 	* to the underlying system. By default, each opened socket is counted as
       
  1047 	* one user.
       
  1048 	*/
       
  1049 	virtual void IncUsers() = 0;
       
  1050 	/**
       
  1051 	* Decrease the "users" counter.
       
  1052 	* For details, see IncUsers().
       
  1053 	*/
       
  1054 	virtual void DecUsers() = 0;
       
  1055 	//
       
  1056 	// Use of the following methods is through the
       
  1057 	// RFlowContext handle
       
  1058 	//
       
  1059 	/**
       
  1060 	* Creates a new (empty) instance of a CFlowContext.
       
  1061 	*
       
  1062 	* @param aOwner Identifies the flow's owner (typically an RFlowContext handle)
       
  1063 	* @param aProtocol Protocol ID
       
  1064 	* @return New object
       
  1065 	*/
       
  1066 	virtual CFlowContext *NewFlowL(const void *aOwner, TUint aProtocol) = 0;
       
  1067 	/**
       
  1068 	* Creates a copy of an instance of a CFlowContext.
       
  1069 	*
       
  1070 	* @param aOwner Identifies the flow's owner (typically an RFlowContext handle)
       
  1071 	* @param aFlow Object to copy
       
  1072 	* @return New object
       
  1073 	*/
       
  1074 	virtual CFlowContext *NewFlowL(const void *aOwner, CFlowContext &aFlow) = 0;
       
  1075 	/**
       
  1076 	* Sets the connect information changed flag on all flows.
       
  1077 	* @return Number of flows.
       
  1078 	*/
       
  1079 	virtual TInt SetChanged() const = 0;
       
  1080 
       
  1081 
       
  1082 //protected:
       
  1083 
       
  1084 	/** Internal API between flow and flow manager. @publishedPartner */
       
  1085 	virtual TInt FlowSetupHooks(CFlowInternalContext &aFlow) = 0;
       
  1086 	/** Internal API between flow and flow manager. @publishedPartner */
       
  1087 	virtual void FlowStartRefresh(CFlowInternalContext &aFlow) = 0;
       
  1088 	//
       
  1089 	// Flow option handling
       
  1090 	//
       
  1091 	/** Internal API between flow and flow manager. @publishedPartner */
       
  1092 	virtual TInt GetFlowOption(TUint aLevel, TUint aName, TDes8 &aOption, const CFlowContext &aFlow) const = 0;
       
  1093 	/** Internal API between flow and flow manager. @publishedPartner */
       
  1094 	virtual TInt SetFlowOption(TUint aLevel, TUint aName, const TDesC8 &aOption, CFlowContext &aFlow) = 0;
       
  1095 	};
       
  1096 
       
  1097 #endif