networkprotocols/tcpipv4v6prt/inc/tcp.h
changeset 0 af10295192d8
child 8 e9cc36e353d4
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 2006-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 // tcp.h - TCP protocol for IPv6/IPv4
       
    15 // TCP protocol class declarations for IPv6/IPv4.
       
    16 //
       
    17 
       
    18 
       
    19 
       
    20 /**
       
    21  @file tcp.h
       
    22  @internalComponent
       
    23 */
       
    24 
       
    25 #ifndef __TCP_H__
       
    26 #define __TCP_H__
       
    27 
       
    28 #include "in_trans.h"
       
    29 #include <ip6_hdr.h>
       
    30 #include <tcp_hdr.h>
       
    31 #include <in_chk.h>
       
    32 #include "frag.h"
       
    33 #include "inet6log.h"
       
    34 #include <in6_opt.h>
       
    35 
       
    36 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
    37 #include <in_sock.h>
       
    38 #endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
    39 
       
    40 // Define the following macro here. Do NOT use macro statement in mmp file to define this.
       
    41 //	The macro will be used in source files to confirm the right modifed header file is used.
       
    42 //	Using macro statement in mmp file disables the trick.
       
    43 //#define FJ_USE_VARIANT_TIMER
       
    44 
       
    45 #ifdef FJ_USE_VARIANT_TIMER
       
    46 #include <FjVariantTimer.h>
       
    47 #endif
       
    48 
       
    49 //
       
    50 // Constants affecting protocol performance
       
    51 //
       
    52 const TUint KOneSecondUs      = 1000000;    //< Help for converting longer times to microseconds
       
    53 
       
    54 const TUint KTcpMaximumWindow = 0x3fffffff;  //< Maximum receive window size
       
    55 const TUint KTcpMinimumWindow =      1024;  //< Minimum receive window size
       
    56 const TUint KTcpDefaultRcvWnd = 48 * 1024;  //< Default receive window size
       
    57 const TUint KTcpDefaultSndWnd = 16 * 1024;  //< Default send window size
       
    58 
       
    59 const TUint KTcpDefaultMSS    =     65535;  //< By default, MSS is not limited by user
       
    60 const TUint KTcpStandardMSS   =       536;  //< Internet standard MSS
       
    61 const TUint KTcpMinimumMSS    =        64;  //< Minimum acceptable MSS.
       
    62 const TUint KTcpMaxTransmit   =         2;  //< Transmit at most this many segments at one time.
       
    63 
       
    64 const TUint KTcpMinRTO        =   1000000;  //< us (1s)
       
    65 const TUint KTcpMaxRTO        =  60000000;  //< us (60s)
       
    66 const TUint KTcpInitialRTO    =   3000000;  //< us (3s)
       
    67 const TUint KTcpSrttSmooth    =         8;  //< alpha = 1/8
       
    68 const TUint KTcpMdevSmooth    =         4;  //< beta  = 1/4
       
    69 const TUint KTcpRTO_K         =         4;  //< RTO = SRTT = 4 * RTTVAR
       
    70 
       
    71 const TUint KTcpAckDelay      =    200000;  //< us (200ms)
       
    72 const TUint KTcpMsl2Delay     =  60000000;  //< us (2x30s)
       
    73 
       
    74 const TUint KTcpSynRetries    = 5;          //< Maximum retransmit attempts during connect.
       
    75 const TUint KTcpMaxRetries1   = 3;          //< Maximum retransmit attempts before MTU reduction.
       
    76 const TUint KTcpMaxRetries2   = 12;	    //< Maximum retransmit attempts during transmission.
       
    77 
       
    78 const TUint KTcpReordering    = 3;          //< Worst case packet reordering in network.
       
    79 const TUint KTcpInitialCwnd   = 2;          //< Initial congestion window
       
    80 const TUint KTcpLtxWindow     = 2;          //< Limited transmit window (2 segments)
       
    81 
       
    82 
       
    83 const TUint KTcpNumKeepAlives = 8;	    //< Number of keepalive probes before quitting.
       
    84 const TUint KTcpKeepAliveRxmt = 75;	    //< Interval for retransmitted keepalives (seconds).
       
    85 const TUint KTcpKeepAliveIntv = 2 * 3600;   //< Default interval between keepalives (seconds => 2 h).
       
    86 const TUint KTcpKeepAliveTH   = 30;		//< Minimum time between triggered KeepAlives (seconds)
       
    87 
       
    88 const TInt KTcpFinPersistency = 3;		//< Default for tcp_fin_persistency.
       
    89 const TInt KTcpMaxLingerTime = 1800;	//< Max Linger Timeout in seconds (= 30 min).
       
    90 
       
    91 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
    92 const TUint KTcpDefaultRcvMaxWnd = 0x40000; // TCP Receive Max window = 262144
       
    93 #endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
    94 
       
    95 //
       
    96 // Maximum number of remembered urgent pointers. If the number of
       
    97 // separate pending urgent bytes exceeds this number the urgent
       
    98 // data bytes will start appearing in the received data (as if
       
    99 // inlined).
       
   100 //
       
   101 // Discussion: We use a fairly light-weight method of removing
       
   102 // out-of-band data from the data stream that involves no extra
       
   103 // copying. BSD does it the hard way but still sometimes leaves
       
   104 // droppings in the data stream. So, why bother? Increasing the
       
   105 // number below reduces the probability of an out-of-band character
       
   106 // appearing in the data stream. The cost is 4*n bytes state
       
   107 // variable space. -ML
       
   108 //
       
   109 const TInt KTcpUpMax         = 5;
       
   110 
       
   111 
       
   112 typedef TInet6Checksum<TInet6HeaderTCP> TTcpPacket;
       
   113 
       
   114 
       
   115 /**
       
   116  * TCP timer
       
   117  */
       
   118 #ifdef FJ_USE_VARIANT_TIMER
       
   119 class CTcpTimer : public DCM::CVariantTimer
       
   120 #else
       
   121 class CTcpTimer : public CTimer
       
   122 #endif
       
   123 	{
       
   124 public:
       
   125 #ifdef FJ_USE_VARIANT_TIMER
       
   126 	CTcpTimer(TCallBack& aCallBack, TInt aPriority = KInet6DefaultPriority)
       
   127     : DCM::CVariantTimer(aPriority), iCallBack(aCallBack.iFunction, aCallBack.iPtr)
       
   128 #else
       
   129   CTcpTimer(TCallBack& aCallBack, TInt aPriority = KInet6DefaultPriority)
       
   130 		: CTimer(aPriority), iCallBack(aCallBack.iFunction, aCallBack.iPtr)
       
   131 #endif
       
   132 		{ CActiveScheduler::Add(this); }
       
   133 	virtual void RunL() { iCallBack.CallBack(); }
       
   134 	virtual void InitL() { ConstructL(); }
       
   135 	void Start(TUint aMicroSeconds)
       
   136 		{
       
   137 		if (!IsActive())
       
   138 			After(aMicroSeconds);
       
   139 		}
       
   140 
       
   141 	void Restart(TUint aMicroSeconds)
       
   142 		{
       
   143 		if (IsActive())
       
   144 			Cancel();
       
   145 		After(aMicroSeconds);
       
   146 		}
       
   147 
       
   148 	private:
       
   149 		TCallBack iCallBack;
       
   150 	};
       
   151 
       
   152 
       
   153 /**
       
   154  * TCP reassembly queue
       
   155  */
       
   156 class RMBufTcpFrag : public RMBufFrag
       
   157 	{
       
   158 public:
       
   159 	TUint Offset();
       
   160 	TUint FragmentLength();
       
   161 	void Join(RMBufChain& aChain);
       
   162 	};
       
   163 
       
   164 typedef RMBufFragQ<RMBufTcpFrag> RMBufTcpFragQ;
       
   165 
       
   166 
       
   167 /**
       
   168  * TCP Protocol
       
   169  */
       
   170 class CProtocolTCP6 : public CProtocolInet6Transport
       
   171 	{
       
   172 public:
       
   173 	CProtocolTCP6();
       
   174 	CProtocolTCP6& operator=(const CProtocolTCP6&);
       
   175 	virtual ~CProtocolTCP6();
       
   176 	virtual CServProviderBase *NewSAPL(TUint aProtocol);
       
   177 	virtual void InitL(TDesC& aTag);
       
   178 	virtual void StartL();
       
   179 	virtual void Identify(TServerProtocolDesc *) const;
       
   180 	//virtual TInt GetOption(TUint level,TUint name,TDes8 &option,CProtocolBase* aSourceProtocol=NULL);
       
   181 	//virtual TInt SetOption(TUint level, TUint aName,const TDesC8 &option,CProtocolBase* aSourceProtocol=NULL);
       
   182 	virtual TInt Send(RMBufChain& aPDU,CProtocolBase* aSourceProtocol=NULL);
       
   183 	virtual void Process(RMBufChain& aPacket, CProtocolBase *aSourceProtocol = NULL);
       
   184 	static void Describe(TServerProtocolDesc&);
       
   185 	TUint32 RandomSequence();
       
   186 
       
   187 	TInt SendControlSegment(RFlowContext *aFlow,
       
   188 		const TSockAddr& aSrcAddr, const TSockAddr& aDstAddr,
       
   189 		TUint8 aFlags, TTcpSeqNum aSeq, TTcpSeqNum aAck,
       
   190 		TUint32 aWnd = 0, TUint32 aUP = 0);
       
   191 
       
   192 	//
       
   193 	// TCP Configuration Parameters
       
   194 	//
       
   195 	TUint MSS() const               { return iMSS; }
       
   196 	TUint RecvBuf() const           { return iRecvBuf; }
       
   197 	TUint SendBuf() const           { return iSendBuf; }
       
   198 	TUint MinRTO() const            { return iMinRTO; }
       
   199 	TUint MaxRTO() const            { return iMaxRTO; }
       
   200 	TUint InitialRTO() const        { return iInitialRTO; }
       
   201 	TUint SrttSmooth() const        { return iSrttSmooth; }
       
   202 	TUint MdevSmooth() const        { return iMdevSmooth; }
       
   203 	TUint RTO_K() const             { return iRTO_K; }
       
   204 	TUint RTO_G() const             { return iRTO_G; }
       
   205 	TUint ClockGranularity() const  { return iClockGranularity; }
       
   206 	TUint AckDelay() const          { return iAckDelay; }
       
   207 	TUint Msl2Delay() const         { return iMsl2Delay; }
       
   208 	TUint SynRetries() const        { return iSynRetries; }
       
   209 	TUint Retries1() const          { return iRetries1; }
       
   210 	TUint Retries2() const          { return iRetries2; }
       
   211 	TUint ProbeStyle() const        { return iProbeStyle; }
       
   212 	TUint InitialCwnd() const       { return iInitialCwnd; }
       
   213 	TUint LtxWindow() const         { return iLtxWindow; }
       
   214 	TUint RFC2414() const           { return iRFC2414; }
       
   215 	TUint Reordering() const        { return iReordering; }
       
   216 	TUint MaxBurst() const          { return iMaxBurst; }
       
   217 	TUint TimeStamps() const        { return iTimeStamps; }
       
   218 	TUint Sack() const              { return iSack; }
       
   219 	TUint LocalTimeWait() const     { return iLocalTimeWait; }
       
   220 	TUint StrictNagle() const       { return iStrictNagle; }
       
   221 	TUint PushAck() const           { return iPushAck; }
       
   222 	TUint FRTO() const				{ return iFRTO; }
       
   223 	TUint DSack() const				{ return iSack && iDSack; }
       
   224 	TUint KeepAliveIntv() const		{ return iKeepAliveIntv; }
       
   225 	TUint KeepAliveRxmt() const		{ return iKeepAliveRxmt; }
       
   226 	TUint NumKeepAlives() const		{ return iNumKeepAlives; }
       
   227 	TUint DstCache() const			{ return iDstCache; }
       
   228 	TUint Ecn() const				{ return iEcn; }
       
   229 	TUint FinPersistency() const	{ return iFinPersistency; }
       
   230 	TUint SpuriousRtoResponse() const { return iSpuriousRtoResponse; }
       
   231 	TInt WinScale()					{ return iWinScale; }
       
   232 	TInt AlignOpt() const 			{ return iAlignOpt; }
       
   233 
       
   234 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   235 	//Function to set and get receive window
       
   236 	void SetRecvWin(TUint aRecvWin) { iRecvBuf = aRecvWin;}
       
   237 	TUint GetRecvWinSize()			{ return iRecvBuf;	 }
       
   238 	TUint RecvMaxWnd()              { return iTcpMaxRecvWin;}
       
   239 #endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   240 
       
   241 #ifdef _LOG
       
   242 	static void LogPacket(char aDir, RMBufChain& aPacket, RMBufPktInfo *info = 0, TInt aOffset = 0);
       
   243 #endif
       
   244 
       
   245 private:
       
   246 
       
   247 	TUint	iMSS;
       
   248 	TUint   iRecvBuf;
       
   249 	TUint   iSendBuf;
       
   250 	TUint   iMinRTO;
       
   251 	TUint   iMaxRTO;
       
   252 	TUint   iInitialRTO;
       
   253 	TUint   iSrttSmooth;
       
   254 	TUint   iMdevSmooth;
       
   255 	TUint   iRTO_G;
       
   256 	TUint   iRTO_K;
       
   257 	TUint   iMaxBurst;
       
   258 	TUint   iAckDelay;
       
   259 	TUint   iSynRetries;
       
   260 	TUint   iRetries1;
       
   261 	TUint   iRetries2;
       
   262 	TUint   iProbeStyle;
       
   263 	TUint   iClockGranularity;
       
   264 	TUint   iMsl2Delay;
       
   265 	TUint   iInitialCwnd;
       
   266 	TUint   iLtxWindow;
       
   267 	TUint   iReordering;
       
   268 	TUint	iKeepAliveIntv;
       
   269 	TUint	iKeepAliveRxmt;
       
   270 	TUint	iNumKeepAlives;
       
   271 	TUint	iFinPersistency;
       
   272 	TInt8   iWinScale;		//< value of "tcp_winscale" option: -1 ... 7
       
   273 
       
   274 	// Flags
       
   275 	TUint  	iTimeStamps:1;
       
   276 	TUint  	iSack:1;
       
   277 	TUint  	iLocalTimeWait:1;
       
   278 	TUint  	iStrictNagle:1;
       
   279 	TUint  	iRFC2414:1;
       
   280 	TUint 	iPushAck:1;
       
   281 	TUint 	iFRTO:1;
       
   282 	TUint 	iDSack:1;
       
   283 	TUint  	iDstCache:1;
       
   284 	TUint	iAlignOpt:1;	//< Set if TCP options should be aligned using NOP option.
       
   285 
       
   286 	// Ecn has 3 reasonable settings: 0 = disable, 1 = enable with ECT(1), 2 = enable with ECT(0).
       
   287 	// Old specification used only ECT(0), so there may be routers out there that only understand
       
   288 	// ECT(0) but not ECT(1).
       
   289 	TUint	iEcn:2;
       
   290 	
       
   291 	// 8 possible values should be enough for spurious response alternatives.
       
   292 	TUint	iSpuriousRtoResponse:3;
       
   293 
       
   294 	TUint32 iRandomIncrement;
       
   295 	RMBufAllocator iBufAllocator;
       
   296 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   297 	TUint iTcpMaxRecvWin;
       
   298 #endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   299 	};
       
   300 
       
   301 
       
   302 /**
       
   303  * TCP Socket Provider.
       
   304 	*/
       
   305 class CProviderTCP6 : public CProviderInet6Transport
       
   306 	{
       
   307 	friend class CProtocolTCP6;
       
   308 
       
   309 public:
       
   310 	CProviderTCP6(CProtocolInet6Base* aProtocol);
       
   311 	virtual ~CProviderTCP6();
       
   312 	virtual void InitL();
       
   313 	virtual void Start();
       
   314 	virtual TInt GetOption(TUint level,TUint name,TDes8 &anOption) const;
       
   315 	virtual void Ioctl(TUint level,TUint name,TDes8* anOption);
       
   316 	virtual void CancelIoctl(TUint aLevel, TUint aName);
       
   317 	virtual TInt SetOption(TUint level,TUint name, const TDesC8 &anOption);
       
   318 	virtual TInt SetRemName(TSockAddr &aAddr);
       
   319 	virtual void Shutdown(TCloseType option);
       
   320 	virtual void ActiveOpen();
       
   321 	virtual TInt PassiveOpen(TUint aQueSize);
       
   322 	virtual void ErrorExpire(TInt aError);
       
   323 	virtual void CanSend();
       
   324 
       
   325 	// PRTv1.0 send and receive methods
       
   326 	virtual TUint Write(const TDesC8 &aDesc,TUint options, TSockAddr* aAddr=NULL);
       
   327 	virtual void GetData(TDes8 &aDesc,TUint options,TSockAddr *aAddr=NULL);
       
   328 
       
   329 	// PRTv1.5 send and receive methods
       
   330 	virtual TInt Write(RMBufChain& aData, TUint aOptions, TSockAddr* anAddr=NULL);
       
   331 	virtual TInt GetData(RMBufChain& aData, TUint aLength, TUint aOptions, TSockAddr* anAddr=NULL);
       
   332 
       
   333 	// Parent socket methods
       
   334 	TInt CreateChild(CProviderTCP6*& aSAP);
       
   335 	void DetachChild(CProviderTCP6* aSAP);
       
   336 	TInt CompleteChildConnect(CProviderTCP6* aSAP);
       
   337 	inline void SetChildDeleted(TBool aDeleted);
       
   338 
       
   339 	virtual void Process(RMBufChain& aPacket, CProtocolBase *aSourceProtocol = NULL);
       
   340 	CProtocolTCP6* Protocol() const { return (CProtocolTCP6*)iProtocol; }
       
   341 
       
   342 	virtual void IcmpError(TInt aError, TUint aOperationMask, TInt aType, TInt aCode,
       
   343 		const TInetAddr& aSrcAddr, const TInetAddr& aDstAddr, const TInetAddr& aErrAddr);
       
   344 
       
   345 	inline void LingerTimeout();
       
   346 
       
   347 	virtual TInt CheckPolicy(const TSecurityPolicy& aPolicy, const char *aDiagnostic);
       
   348 
       
   349 private:
       
   350     RMBufAllocator iBufAllocator;
       
   351 	// Connection state
       
   352 	enum TTcpStateEnum
       
   353 		{
       
   354 		ETcpInitial      = 0x0001,
       
   355 		ETcpListen       = 0x0002,
       
   356 		ETcpSynSent      = 0x0004,
       
   357 		ETcpSynReceived  = 0x0008,
       
   358 		ETcpEstablished  = 0x0010,
       
   359 		ETcpFinWait1     = 0x0020,
       
   360 		ETcpFinWait2     = 0x0040,
       
   361 		ETcpCloseWait    = 0x0080,
       
   362 		ETcpClosing      = 0x0100,
       
   363 		ETcpLastAck      = 0x0200,
       
   364 		ETcpTimeWait     = 0x0400,
       
   365 		ETcpClosed       = 0x0800,
       
   366 		ETcpConnect      = 0x1000
       
   367 		} iState;
       
   368 
       
   369 	//
       
   370 	//.    Send Window Management
       
   371 	//
       
   372 	//      SND.UNA - send unacknowledged
       
   373 	//      SND.NXT - send next
       
   374 	//      SND.WND - send window
       
   375 	//      SND.UP  - send urgent pointer
       
   376 	//      SND.WL1 - segment sequence number used for last window update
       
   377 	//      SND.WL2 - segment acknowledgment number used for last window update
       
   378 	//      ISS     - initial send sequence number
       
   379 	//
       
   380 	struct TTcpSendSequence
       
   381 		{
       
   382 		TTcpSeqNum UNA;
       
   383 		TTcpSeqNum NXT;
       
   384 		TTcpSeqNum WL1;
       
   385 		TTcpSeqNum WL2;
       
   386 		TTcpSeqNum UP;
       
   387 		TUint32    WND;
       
   388 		} iSND;
       
   389 
       
   390 	//
       
   391 	//    Receive Window Management
       
   392 	//
       
   393 	//      RCV.NXT - receive next
       
   394 	//      RCV.WND - receive window
       
   395 	//      RCV.UP  - receive urgent pointer
       
   396 	//      IRS     - initial receive sequence number
       
   397 	//
       
   398 	struct TTcpRecvSequence
       
   399 		{
       
   400 		TTcpSeqNum NXT;
       
   401 		//TTcpSeqNum UP;
       
   402 		TUint32    WND;
       
   403 		} iRCV;
       
   404 	TTcpSeqNum        iFinSeq;
       
   405 
       
   406 	// Window updates
       
   407 	TUint32           iFreeWindow;
       
   408 	TUint32           iAdvertisedWindow;
       
   409 
       
   410 	// Retransmission control
       
   411 	TTcpSeqNum	    iLastAck;
       
   412 	TTcpSeqNum	    iTransmitSeq;
       
   413 	TTcpSeqNum	    iRecoverSeq;
       
   414 	TTcpSeqNum	    iSendHigh;
       
   415 	TUint		    iDupAcks;
       
   416 	TUint		    iLastWnd;
       
   417 
       
   418 	// Queue management
       
   419 	RMBufAsyncPktQ	iSendQ;
       
   420 	RMBufAsyncPktQ  iRecvQ;
       
   421 	RMBufTcpFragQ	iFragQ;
       
   422 	RMBufSockQ	    iSockOutQ;
       
   423 	RMBufSockQ	    iSockInQ;
       
   424 	TUint		    iSockOutQLen;
       
   425 	TUint		    iSockInQLen;
       
   426 	TUint		    iSockOutBufSize;
       
   427 	TUint		    iSockInBufSize;
       
   428 	TUint			iNewData;
       
   429 	TUint           iPending;
       
   430 	
       
   431 
       
   432 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   433 	
       
   434 	//Window size for startup case
       
   435 	TUint32 iTcpMaxRecvWin;
       
   436     //New window set by the bearer in case of window shrink
       
   437 	TUint32 iNewTcpWindow;
       
   438 	//Size of buffer read by the application from the TCP receive buffer
       
   439 	//but is not transparent while advertising a new TCP window to the sender.	
       
   440 	TUint32 iHiddenFreeWindow;
       
   441 	//  Size of Window Shrink
       
   442 	TUint32 iShrinkedWindowSize;
       
   443 	// Window size set by user. This will override the default values for the bearers
       
   444 	TBool   iWindowSetByUser;
       
   445 #endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   446 
       
   447 	// Maximum Segment Sizes
       
   448 	TUint           iMSS;   //< Maximum set by user
       
   449 	TUint		    iSMSS;  //< Send MSS
       
   450 	TUint		    iRMSS;  //< Receive MSS
       
   451 
       
   452 	// Asynchronous events
       
   453 	CAsyncCallBack  *iTransmitter;
       
   454 	CTcpTimer	    *iDelayAckTimer;
       
   455 	CTcpTimer	    *iRetransTimer;
       
   456 	CTcpTimer	    *iLingerTimer;
       
   457 
       
   458 	// RTT timing
       
   459 	TTime		    iStartTime;		  //< Time at the beginning of connection.
       
   460 	TUint32	    	iTimeStamp;		  //< Last time stamp taken
       
   461 	TTcpSeqNum	    iTimingSeq;
       
   462 	TUint32	    	iTsRecent;
       
   463 
       
   464 	// RTO calculation
       
   465 	TUint32	    iRTO;
       
   466 	TUint32	    iSRTT;
       
   467 	TUint32	    iMDEV;
       
   468 	TUint		iBackoff;
       
   469 
       
   470 	// Delay spike detection
       
   471 	TUint32     iLastTimeout;         //< Timestamp of last RTO
       
   472 	
       
   473 	// Keep-Alive triggering
       
   474 	TUint32		iLastTriggeredKeepAlive; //< Last triggered keep-alive
       
   475 
       
   476 	// Congestion control
       
   477 	TUint32	    iCwnd;
       
   478 	TUint32     iLwnd;
       
   479 	TUint32	    iSsthresh;
       
   480 	TTcpSeqNum  iQuenchSeq;           //< Store right window edge at source quench
       
   481 	TTcpSeqNum	iPartialSeq;
       
   482 
       
   483 	// TCP options
       
   484 	TTcpOptions	iOptions;
       
   485 
       
   486 	// Server socket state
       
   487 	TUint		    iListenQueueSize;	  //< Listen queue size.
       
   488 	TUint		    iConnectCount;	  //< Number active connect attempts;
       
   489 	CProviderTCP6	*iParent;		  //< Parent socket
       
   490 	CProviderTCP6   **iListenQueue;       //< Array holding pointers to child sockets
       
   491 	TBool			iChildDeleted;		//< Flag for notifying parent that a child was deleted by SocketServer
       
   492 
       
   493 	// Urgent data handling
       
   494 	TTcpSeqNum        iUpArray[KTcpUpMax];
       
   495 	TInt              iUpIndex;
       
   496 	TInt              iUpCount;
       
   497 
       
   498 	// Large peek offset
       
   499 	TInt              iCopyOutOffset;
       
   500 
       
   501 	// SACK book keeping
       
   502 	SequenceBlockQueue  iSacked;
       
   503 
       
   504 	// FACK book keeping
       
   505 	TUint32           iRetranData;
       
   506 
       
   507 	// Needed state information for F-RTO/DCLOR retransmission
       
   508 	TUint32			iFRTOsent;  //< True, if rto was sent and no acks have yet arrived
       
   509 	TTcpSeqNum		iRealSendHigh;  //< iSendHigh is not real with SACK
       
   510 
       
   511 	// -1=linger disabled, >=0 linger enabled with given time in seconds.
       
   512 	TInt			iLinger;
       
   513 
       
   514 	// Window scaling factor for the send window, advertised by the other end.
       
   515 	TUint8			iSndWscale:4;
       
   516 
       
   517 	// Window scaling factor for receive window, based on ini settings.
       
   518 	TUint8			iRcvWscale:4;
       
   519 
       
   520 	TUint iRetryAck;  // to keep count of the ACKs that inform missing segments
       
   521 
       
   522 	// Flags
       
   523 	struct TTcpFlags
       
   524 		{
       
   525 		// Additional TCP state
       
   526 		TUint32		iStarted:1;		  //< Protocol has been started
       
   527 		TUint32	    iFastRetransMode:1;   //< We're in fast retransmit mode
       
   528 		TUint32	    iTransmitPending:1;   //< We have segments waiting for flow
       
   529 		TUint32	    iRetransmitPending:1; //< We have a retransmission waiting for flow
       
   530 		TUint32     iPeerHasReneged:1;    //< The peer has reneged and might do it again.
       
   531 		TUint32	    iTiming:1;            //< We're timing a segment round trip
       
   532 		TUint32     iCloseNotified:1;     //< Application has been notified of received FIN.
       
   533 		TUint32     iUrgentMode:1;        //< Application is in urgent mode.
       
   534 		TUint32     iNextIsUrgent:1;      //< Next Write() call contains urgent data.
       
   535 		TUint32     iFinReceived:1;       //< We have received a FIN from the peer
       
   536 		TUint32     iDataSentIoctl:1;     //< KIoctlTcpNotifyDataSent ioctl is active
       
   537 		TUint32     iCompleteRecv:1;      //< Force RSocket::Recv() to complete (urgent data ahead)
       
   538 		TUint32     iNotifyUrgent:1;      //< Notify application of urgent data.
       
   539 		TUint32     iDoPMTUD:1;           //< Do path MTU discovery?
       
   540 		TUint32	    iHaveKeepAlive:1;	  //< Keep-Alive option is set.
       
   541 		TUint32     iHaveTriggeredKeepAlive:1; //< Triggered Keep-Alive option is set.
       
   542 		TUint32	    iEcnHaveCongestion:1; //< ECN receiver has got CE bit, but not yet CWR.
       
   543 		TUint32	    iEcnSendCWR:1;	  //< ECN sender has got ECE. Next seg should have CWR set.
       
   544 		TUint32	    iKeepInterfaceUp:1;	  //< Storage for KeepInterfaceUp during connection establishment.
       
   545 
       
   546 		// Enabled TCP options
       
   547 		TUint32	    iUseTimeStamps:1;     //< We're using timestamps for timing round trips
       
   548 		TUint32	    iSackOk:1;            //< We're using selective acknowledgements
       
   549 		TUint32     iOobInline:1;         //< Send out-of-band data inline.
       
   550 		TUint32     iNoDelay:1;           //< Disable Nagle.
       
   551 		TUint32	    iCork:1;		  //< Send only full-sized segments.
       
   552 		TUint32	    iEcn:1;		  //< We're using Explicit Congestion Notification.
       
   553 		} iFlags;
       
   554 
       
   555 private:
       
   556 
       
   557 	//
       
   558 	// Private implementation methods
       
   559 	//
       
   560 	inline TInt Min(TInt a, TInt b) const;
       
   561 	inline TUint MinUU(TUint a, TUint b) const;	
       
   562 	inline TInt MinUS(TUint a, TInt b) const;
       
   563 	inline TInt MinSU(TInt a, TUint b) const;
       
   564 	inline TInt Max(TInt a, TInt b) const;
       
   565 
       
   566 	void Stop();
       
   567 	void FreeQueues();
       
   568 	void Close();
       
   569 
       
   570 	inline void EnterState(TTcpStateEnum aState);
       
   571 	inline TBool InState(TUint aStateSet) const;
       
   572 
       
   573 	TInt SendSegment(TUint8 aFlags, TTcpSeqNum aSeq, TUint32 aLen = 0);
       
   574 	TInt SendDataSegment(TTcpSeqNum aSeq, TBool aNagleOverride = EFalse);
       
   575 
       
   576 	inline TInt SendSegment(TUint8 aFlags);
       
   577 	inline void SendDelayACK();
       
   578 	inline TInt SendReset(TTcpSeqNum aSequence, const TSockAddr& aDstAddr, const TSockAddr& aSrcAddr);
       
   579 	inline TInt SendReset(TTcpSeqNum aSequence);
       
   580 	inline TInt SendResetNoSync(TTcpSeqNum aAckSequence, const TSockAddr& aDstAddr, const TSockAddr& aSrcAddr);
       
   581 	inline TInt SendResetNoSync(TTcpSeqNum aAckSequence);
       
   582 	inline void SchedTransmit();
       
   583 	inline void SchedRetransmit();
       
   584 	inline void ReSchedRetransmit();
       
   585 	inline void CancelTransmit();
       
   586 	inline void CancelRetransmit();
       
   587 	inline void CancelDelayACK();
       
   588 	inline TUint32 TimeStamp();
       
   589 	inline TUint32 PathMSS();
       
   590 	inline TUint32 EffectiveMSS();
       
   591 	inline TUint32 LinkRMSS();
       
   592 	inline TInt SockInQOffset(TTcpSeqNum aSeq) const;
       
   593 
       
   594 	inline TTcpSeqNum UrgentHigh() const;
       
   595 	inline TInt UrgentOffset() const;
       
   596 	inline TInt UrgentOffset(TInt aIndex) const;
       
   597 	inline TInt SockInQLen() const;
       
   598 
       
   599 	inline TBool CanForwardTransmit();
       
   600 	inline void SetEcn(TInt aFlag);
       
   601 	inline TBool IsLandAttack(RMBufRecvInfo *aInfo);
       
   602 
       
   603 	void RememberUrgentPointer(TTcpSeqNum aUp);
       
   604 	void ForgetUrgentPointer();
       
   605 	TInt GetUrgent(TInt& aChar, TUint aOptions);
       
   606 
       
   607 	void Transmit();
       
   608 	void ClearRTT();
       
   609 	void UpdateRTO(TUint32 aRTT);
       
   610 	void ResetRTO();
       
   611 	void ResetCwnd(TUint aSMSS);
       
   612 	void SchedMsl2Wait();
       
   613 	void ProcessSegments();
       
   614 	void SendSegments(TBool aNagleOverride = EFalse);
       
   615 	void RetransmitTimeout();
       
   616 	void RetransmitSegments();
       
   617 	void ClearSYNSettings();
       
   618 
       
   619 	/**
       
   620 	 * Reduce congestion window. The following events may cause this: 1. ICMP Source Quench,
       
   621 	 * 2. notification from link layer, 3. ECN congestion echo. The method ensures that congestion
       
   622 	 * window is not reduced more frequently than once in RTT.
       
   623 	 *
       
   624 	 * @return ETrue if cwnd was reduced, EFalse if it was not.
       
   625 	 */
       
   626 	TBool SourceQuench();
       
   627 
       
   628 	void SendSYN();
       
   629 	void CompleteIoctl(TInt aError);
       
   630 	void Detach();
       
   631 	void Expire();
       
   632 
       
   633 	void ReadDestinationCache();
       
   634 	void StoreDestinationCache();
       
   635 	
       
   636 	void DetachIfDead();
       
   637 	void DetachFromInterface();
       
   638 
       
   639 	/**
       
   640 	 * Check the size of receive buffers and determine if window scaling is needed
       
   641 	 * on our part.
       
   642 	 *
       
   643 	 * @return The scale factor that would be required due to buffer size settings.
       
   644 	 */
       
   645 	TUint8 NeedWindowScale();
       
   646 	
       
   647 	void SpuriousTimeout(TUint aAcked);
       
   648 
       
   649 	inline void StoreKeepInterfaceUp();
       
   650 
       
   651 	// small methods for keep-alive option
       
   652 	void KeepAliveTimeout();  //< Keep-Alive related timeout has expired.
       
   653 	void ResetKeepAlives();   //< Resetting keep-alive probe timer when connection becomes idle
       
   654 	inline TBool CanFireKeepAlives()  //< ETrue when keep-alive probe timer can be activated
       
   655 		{ return iSND.NXT == iSND.UNA && iSND.WND > 0 && iFlags.iHaveKeepAlive; }
       
   656 	inline TBool CanTriggerKeepAlive(); //< ETrue if TCP should send triggered keep-alive
       
   657 
       
   658 	TInt Send(TDualBufPtr& aBuf, TInt aLength, TUint aOptions);
       
   659 	TInt Recv(TDualBufPtr& aBuf, TInt aLength, TUint aOptions);
       
   660 
       
   661 	static TInt SenderCallBack(TAny* aProviderTCP);
       
   662 	static TInt ReceiverCallBack(TAny* aProviderTCP);
       
   663 	static TInt DelayAckCallBack(TAny* aProviderTCP);
       
   664 	static TInt TransmitterCallBack(TAny* aProviderTCP);
       
   665 	static TInt RetransmitterCallBack(TAny* aProviderTCP);
       
   666 	static TInt LingerTimerCallBack(TAny* aProviderTCP);
       
   667 
       
   668 #ifdef _LOG
       
   669 public:
       
   670 	const TText *TcpState(TUint aState = ~0L);
       
   671 #endif
       
   672 
       
   673 	};
       
   674 
       
   675 	
       
   676 //
       
   677 // Private implementation methods
       
   678 //
       
   679 inline TInt CProviderTCP6::Min(TInt a, TInt b) const { return (a < b) ? a : b; }
       
   680 inline TUint CProviderTCP6::MinUU(TUint a, TUint b) const { return (a < b) ? a : b; }
       
   681 inline TInt CProviderTCP6::MinUS(TUint a, TInt b) const 
       
   682 	{
       
   683 	if(a > KMaxTInt16)
       
   684 		return b;
       
   685 	else
       
   686 		return Min(TInt(a), b);
       
   687 	}
       
   688 inline TInt CProviderTCP6::MinSU(TInt a, TUint b) const
       
   689 	{
       
   690 	if(b > KMaxTInt16)
       
   691 		return a;
       
   692 	else
       
   693 		return Min(a, TInt(b));
       
   694 	}
       
   695 inline TInt CProviderTCP6::Max(TInt a, TInt b) const { return (a > b) ? a : b; }
       
   696 
       
   697 inline void CProviderTCP6::EnterState(TTcpStateEnum aState)
       
   698 	{
       
   699 	LOG(if (aState != iState)
       
   700 		Log::Printf(_L("\ttcp SAP[%u] EnterState(): %s --> %s"),
       
   701 		(TInt)this, TcpState(), TcpState(aState)));
       
   702 	iState = aState;
       
   703 	}
       
   704 
       
   705 inline TBool CProviderTCP6::InState(TUint aStateSet) const
       
   706 	{
       
   707 	return (aStateSet & iState) != 0;
       
   708 	}
       
   709 
       
   710 
       
   711 inline TInt CProviderTCP6::SendSegment(TUint8 aFlags)
       
   712 	{
       
   713 	return SendSegment(aFlags, iSND.NXT, 0);
       
   714 	}
       
   715 
       
   716 inline void CProviderTCP6::SendDelayACK()
       
   717 	{
       
   718 	iDelayAckTimer->Start(Protocol()->AckDelay());
       
   719 	}
       
   720 
       
   721 inline TInt CProviderTCP6::SendReset(TTcpSeqNum aSequence, const TSockAddr& aDstAddr, const TSockAddr& aSrcAddr)
       
   722 	{
       
   723 	return Protocol()->SendControlSegment(iFlow.Status() == EFlow_READY ? &iFlow : NULL,
       
   724 		aDstAddr, aSrcAddr,
       
   725 		KTcpCtlRST, aSequence, 0);
       
   726 	}
       
   727 
       
   728 inline TInt CProviderTCP6::SendReset(TTcpSeqNum aSequence)
       
   729 	{
       
   730 	return SendReset(aSequence, iFlow.FlowContext()->RemoteAddr(), iFlow.FlowContext()->LocalAddr());
       
   731 	}
       
   732 
       
   733 inline TInt CProviderTCP6::SendResetNoSync(TTcpSeqNum aAckSequence, const TSockAddr& aDstAddr, const TSockAddr& aSrcAddr)
       
   734 	{
       
   735 	return Protocol()->SendControlSegment(iFlow.Status() == EFlow_READY ? &iFlow : NULL,
       
   736 		aDstAddr, aSrcAddr,
       
   737 		KTcpCtlRST|KTcpCtlACK, 0, aAckSequence);
       
   738 	}
       
   739 
       
   740 inline TInt CProviderTCP6::SendResetNoSync(TTcpSeqNum aAckSequence)
       
   741 	{
       
   742 	return SendResetNoSync(aAckSequence, iFlow.FlowContext()->RemoteAddr(), iFlow.FlowContext()->LocalAddr());
       
   743 	}
       
   744 
       
   745 inline void CProviderTCP6::SchedTransmit()
       
   746 	{
       
   747 	iTransmitter->CallBack();
       
   748 	}
       
   749 
       
   750 inline void CProviderTCP6::SchedRetransmit()
       
   751 	{
       
   752 	iRetransTimer->Start(iRTO);
       
   753 	}
       
   754 
       
   755 inline void CProviderTCP6::ReSchedRetransmit()
       
   756 	{
       
   757 	iRetransTimer->Restart(iRTO);
       
   758 	}
       
   759 
       
   760 inline void CProviderTCP6::CancelTransmit()
       
   761 	{
       
   762 	iTransmitter->Cancel();
       
   763 	iFlags.iTransmitPending = EFalse;
       
   764 	}
       
   765 
       
   766 inline void CProviderTCP6::CancelRetransmit()
       
   767 	{
       
   768 	iRetransTimer->Cancel();
       
   769 	iFlags.iRetransmitPending = EFalse;
       
   770 	}
       
   771 
       
   772 inline void CProviderTCP6::CancelDelayACK()
       
   773 	{
       
   774 	iDelayAckTimer->Cancel();
       
   775 	}
       
   776 
       
   777 inline TUint32 CProviderTCP6::TimeStamp()
       
   778 	{
       
   779 	TTime now;
       
   780 	now.UniversalTime();
       
   781 #ifdef I64LOW
       
   782 	return I64LOW(now.Int64());
       
   783 #else
       
   784 	return (TUint32)now.Int64().GetTInt();
       
   785 #endif
       
   786 	}
       
   787 
       
   788 /**
       
   789  * Return maximum segment size allowed by transmission path. Following tradition,
       
   790  * the value represents the maximum number of data bytes that can be passed in
       
   791  * a TCP segment with no option headers.
       
   792  */
       
   793 inline TUint32 CProviderTCP6::PathMSS()
       
   794 	{
       
   795 	ASSERT(iFlow.FlowContext() != 0);
       
   796 	return Min(iMSS, iFlow.FlowContext()->PathMtu() - iFlow.FlowContext()->HeaderSize() - KTcpMinHeaderLength);
       
   797 	}
       
   798 
       
   799 /**
       
   800  * Return effective send MSS. Returns the maximum number of data bytes that can
       
   801  * be passed in a TCP segment. Checks both path MTU and MSS advertised by the receiver.
       
   802  * and subtracts the number of bytes taken up by TCP options.
       
   803  * Finally, ensure that MSS is at most half of the socket output buffer size.
       
   804  */
       
   805 inline TUint32 CProviderTCP6::EffectiveMSS()
       
   806 	{
       
   807 	ASSERT(iFlow.FlowContext() != 0);
       
   808 	return Min(Max(Min(iSMSS, PathMSS()) - iOptions.Length(), KTcpMinimumMSS), iSockOutBufSize>>1);
       
   809 	}
       
   810 
       
   811 /**
       
   812  * Return maximum segment that can be received through the current network interface.
       
   813  * Following tradition, this method returns the maximum number of data bytes assuming
       
   814  * the TCP header contains no optons.
       
   815  */
       
   816 inline TUint32 CProviderTCP6::LinkRMSS()
       
   817 	{
       
   818 	ASSERT(iFlow.FlowContext() != 0);
       
   819 	return Min(iMSS, iFlow.FlowContext()->InterfaceRMtu() -
       
   820 		iFlow.FlowContext()->HeaderSize() - KTcpMinHeaderLength);
       
   821 	}
       
   822 
       
   823 /**
       
   824  * Return number of bytes in receive queue without out-of-band data.
       
   825  */
       
   826 inline TInt CProviderTCP6::SockInQLen() const
       
   827 	{
       
   828 	return iFlags.iOobInline ? iSockInQLen : iSockInQLen - iUpCount;
       
   829 	}
       
   830 
       
   831 inline TInt CProviderTCP6::SockInQOffset(TTcpSeqNum aSeq) const
       
   832 	{
       
   833 	return aSeq - iRCV.NXT + iSockInQLen;
       
   834 	}
       
   835 
       
   836 /**
       
   837  * Return sequence number of highest urgent pointer seen so far.
       
   838  * Assumes iUpCount > 0.
       
   839  */
       
   840 inline TTcpSeqNum CProviderTCP6::UrgentHigh() const
       
   841 	{
       
   842 	return iUpArray[(iUpIndex + iUpCount - 1) % KTcpUpMax];
       
   843 	}
       
   844 
       
   845 /**
       
   846  * Return offset to pending urgent data. A negative value means
       
   847  * there is no pending urgent data.
       
   848  */
       
   849 inline TInt CProviderTCP6::UrgentOffset() const
       
   850 	{
       
   851 	return iUpCount ? SockInQOffset(UrgentHigh()) - 1 : -1;
       
   852 	}
       
   853 
       
   854 /**
       
   855  * Return byte offset of the urgent pointer stored at given index.
       
   856  */
       
   857 inline TInt CProviderTCP6::UrgentOffset(TInt aIndex) const
       
   858 	{
       
   859 	return aIndex < iUpCount ? SockInQOffset(iUpArray[(iUpIndex + aIndex) % KTcpUpMax]) - 1 : KMaxTInt;
       
   860 	}
       
   861 
       
   862 /**
       
   863  * Checks if sending new data is possible without being limited by application or
       
   864  * sender or receiver window. This is used for checking whether F-RTO can be applied for sending
       
   865  * new data instead of retransmitting after RTO.
       
   866  *
       
   867  * @return ETrue if some unsent data can be transmitted. 
       
   868  */
       
   869 inline TBool CProviderTCP6::CanForwardTransmit()
       
   870 	{
       
   871 	return Min(iSND.WND, iSockOutQLen) > (iSND.NXT - iSND.UNA);
       
   872 	}
       
   873 
       
   874 
       
   875 /**
       
   876  * Set the status of ECN for this SAP. Two things: set the SAP-specific status flag, and
       
   877  * signal the flag to the IP layer (iface.cpp) by using flow options.
       
   878  *
       
   879  * @param aFlag	0 = disable ECN, 1 = enable ECN with ECT(1), 2 = enable ECN with ECT(0)
       
   880  */
       
   881 inline void CProviderTCP6::SetEcn(TInt aFlag)
       
   882 	{
       
   883 	TPckgBuf<TInt> ecnopt(aFlag);
       
   884 	iFlow.FlowContext()->SetOption(KSolInetIp, KSoIpEcn, ecnopt);
       
   885 	iFlags.iEcn = (aFlag != 0);
       
   886 	}
       
   887 
       
   888 /**
       
   889 Stores the value of KeepInterfaceUp set for the current flow.
       
   890 */
       
   891 inline void CProviderTCP6::StoreKeepInterfaceUp()
       
   892 	{
       
   893 	TPckgBuf<TInt> ifup;
       
   894 	GetOption(KSolInetIp, KSoKeepInterfaceUp, ifup);
       
   895 	iFlags.iKeepInterfaceUp = (ifup() != 0) ? 1 : 0;
       
   896 	}
       
   897 
       
   898 
       
   899 /**
       
   900 Returns ETrue, if source and destination have equal IP address and port.
       
   901 */
       
   902 inline TBool CProviderTCP6::IsLandAttack(RMBufRecvInfo *aInfo)
       
   903 	{
       
   904 	return TInetAddr::Cast(aInfo->iSrcAddr).CmpAddr(TInetAddr::Cast(aInfo->iDstAddr));
       
   905 	}
       
   906 
       
   907 #endif