--- a/networkprotocols/tcpipv4v6prt/src/tcp_sap.cpp Thu Jul 15 20:25:02 2010 +0300
+++ b/networkprotocols/tcpipv4v6prt/src/tcp_sap.cpp Thu Aug 19 11:25:30 2010 +0300
@@ -140,7 +140,8 @@
// state chart above. It would be located between CLOSED and SYN-SENT.
//
-
+//The below is UID of the client(http client) using this option. We are not exposing this right now...
+const TUint32 KSoTcpLingerinMicroSec = 0x101F55F6;
#ifdef _LOG
const TText *CProviderTCP6::TcpState(TUint aState)
{
@@ -260,6 +261,13 @@
iRetransTimer->InitL();
iLingerTimer->InitL();
iSockInBufSize = Protocol()->RecvBuf();
+#ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+ if(iSockInBufSize == Protocol()->RecvBufFromIniFile())
+ iSocketStartupCase = ETrue;
+ else
+ iSocketStartupCase = EFalse;
+#endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
+
iSockOutBufSize = Protocol()->SendBuf();
iSsthresh = KMaxTInt32;
iRTO = Protocol()->InitialRTO();
@@ -619,48 +627,137 @@
iSockInBufSize = KTcpMinimumWindow;
else
{
-
- //If new TCP window is larger then the previous window, increase the
- //iSockInBufSize right now. TCP recv function takes care of
- //advertising a new effective TCP window.
- if (intValue >= iSockInBufSize)
- {
- //Make it Zero so TCP could avoid the
- //TCP window shrinking processing in Recv.
- iNewTcpWindow = 0;
- //FreeWindow has to be increased at the same time.
- iFreeWindow += intValue - iSockInBufSize;
- // Make the new TCP receive buffer change effective now.
- iSockInBufSize = intValue;
- }
- else
- {
- //This sets iNewTcpWindow to a non-zero value, which indicates
- //to the TCP that window is shrunk and process TCP segments
- //which are in air before setting a new TCP receive buffer.
- //TCP Receive window starts moving only when TCP hidden window
- //size exceeds the size of the shrunk window.
-
- iNewTcpWindow = intValue;
- //Even in case of window shrink we can set the receive buffer size
- //immediately. This will be helpful, for processing SYN-ACK and other
- //receiver side processing.
- //For already connected sockets iNewTcpWindow will be taking care
- //of shrinking the window size for that TCP session.
- iSockInBufSize = iNewTcpWindow;
- if( iAdvertisedWindow > iNewTcpWindow )
- {
- iShrinkedWindowSize = iAdvertisedWindow - iNewTcpWindow;
- }
- else
- {
- // No Need to process TCP receive window processing.
- iNewTcpWindow = 0;
- }
- }
-
- }
-
+ //If its the startup case, then there should be no algorithm used to shrink
+ //or expand the window size from the default value provided in the ini file
+ //the new value should be set directly
+ if(iSocketStartupCase)
+ {
+ //Add the extra window to free window pool
+ //if the window being set is greater than what is specified in ini file (startup case), then just overwrite the new window.
+ //Add difference to free window
+ //else set free window to zero
+ if(intValue > iSockInBufSize)
+ iFreeWindow += intValue - iSockInBufSize;
+ else
+ iFreeWindow = 0;
+ //set the buffer
+ iSockInBufSize = intValue;
+ //disable startup flag.
+ iSocketStartupCase = EFalse;
+ }
+ else
+ {
+ // Check for minimum value
+ if (intValue < STATIC_CAST(TInt, KTcpMinimumWindow))
+ {
+ intValue = STATIC_CAST(TInt, KTcpMinimumWindow);
+ }
+ // Handle the situation where the connection has been established and
+ // window scaling is not in use
+ if ( InState( ETcpSynReceived | ETcpEstablished ) && !iRcvWscale )
+ {
+ // Do not allow window sizes larger than 0xFFFF
+ intValue = Min ( intValue, 0xFFFF );
+ }
+
+ // Check whether we are increasing or decreasing window size
+ if ( intValue >= iSockInBufSize )
+ {
+ // New window is larger than current one, check if a
+ // shrinking process is active
+ if ( !iNewTcpWindow )
+ {
+ // Mark new "space" as free, it will be updated to
+ // peer on next operation.
+ iFreeWindow += intValue - iSockInBufSize;
+ }
+ else
+ {
+ // In the middle of shrinking process.
+ if ( iShrinkedWindowSize <= ( intValue - iSockInBufSize ))
+ {
+ // Increment to window size is enough to complete
+ // shrinking process. Update variables and exit
+ // from shrinking process.
+ iFreeWindow = ( intValue - iSockInBufSize ) - iShrinkedWindowSize;
+ iShrinkedWindowSize = 0;
+ iNewTcpWindow = 0;
+ }
+ else
+ {
+ // Not quite there yet but closer. Less to shrink,
+ // update this, but do not exit from shrinking
+ // process
+ iShrinkedWindowSize -= intValue - iSockInBufSize;
+ iNewTcpWindow = intValue;
+ }
+ }
+ }
+ else
+ {
+ // Requested window is smaller than current one. Start or
+ // continue shrinking process. RCV window can be occupied
+ // for two different purpose at the moment
+ // 1. Client data in iSockInQ not read by application
+ // 2. Free window "opened" to peer (iAdvertisedWindow)
+ // When shrinking, we must ensure that when reopening
+ // the window to client there must be truly empty space
+ // in the window. Thus, freeze the right edge of the
+ // window (iRCV.NXT + iRCV.WND stays constant) until
+ // shrinking is completed.
+
+ if ( iNewTcpWindow )
+ {
+ // There is an ongoing shrink process, add the
+ // change to the amount to be shrinked
+ iShrinkedWindowSize += iSockInBufSize - intValue;
+ iNewTcpWindow = intValue;
+ }
+ else
+ {
+ // This is a new shrinking process, count how much
+ // needs to be shrinked
+ iShrinkedWindowSize = iSockInQLen + iRCV.WND;
+ if ( iShrinkedWindowSize >= intValue )
+ {
+ // We need to shrink since the currently occupied
+ // window does not fit to new one
+ iShrinkedWindowSize -= intValue;
+ // There is now free space in the window
+ iFreeWindow = 0;
+ // iNewTcpWindow is used as a state variable for
+ // shrinking
+ iNewTcpWindow = intValue;
+ }
+ else
+ {
+ // No need to shrink since we can fit the current
+ // contents to the new window, update free window
+ // If TCP connection is not yet setup, the free
+ // window will be updated on connection setup,
+ // for existing connection it will be used
+ // next time application reads data
+ if ( iFreeWindow >= ( iSockInBufSize - intValue ))
+ {
+ iFreeWindow -= iSockInBufSize - intValue;
+ }
+ else
+ {
+ // Something wrong. Try to reevaluate...
+ iFreeWindow = intValue - iShrinkedWindowSize;
+ }
+ iShrinkedWindowSize = 0;
+ }
+ }
+ }
+ // Even in case of window shrink we can set the receive buffer size
+ // immediately. This will be helpful, for processing SYN-ACK and other
+ // receiver side processing.
+ // For already connected sockets iNewTcpWindow will be taking care
+ // of shrinking the window size for that TCP session.
+ iSockInBufSize = intValue;
+ }
+ }
}
break;
#endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
@@ -695,6 +792,11 @@
}
break;
+ case KSoTcpLingerinMicroSec:
+ RDebug::Printf("TSoTcpLingerinMicroSec is set");
+ //Enable micro sec calculation for TCP linger timer. User (currently just exposed to browser)
+ //will specify linger time in microsecs.
+ iMicroSecCalcFlag=ETrue;
case KSoTcpLinger:
if (aOption.Length() < (TInt)sizeof(TSoTcpLingerOpt))
{
@@ -1102,7 +1204,16 @@
// Start linger timer. RSocket::Close() returns when timer
// expires or when all data has been succesfully transmitted.
//
- iLingerTimer->Start(iLinger * KOneSecondInUs);
+ if(iMicroSecCalcFlag)
+ {
+ //expecting iLinger timer to be specified in microsec.This will be set currently by browser where in
+ //it is expected to be close with in certian time
+ iLingerTimer->Start(iLinger * 1);
+ }
+ else
+ {
+ iLingerTimer->Start(iLinger * KOneSecondInUs);
+ }
}
SchedTransmit();
@@ -1362,32 +1473,23 @@
//if This is true, then it is a case of TCP window shrink and we need
//to handle it.
if ( iNewTcpWindow )
- {
- //Log this message for information, that Window is shrinked
- LOG(Log::Printf(_L("\ttcp SAP[%u] TCP window shrinking mode on"), (TInt)this));
-
- //Increase the hidden free TCP receive window.
- iHiddenFreeWindow += aLength;
-
- if (iHiddenFreeWindow >= iShrinkedWindowSize)
- {
- //Disable window shrink processing, so that TCP could switch
- //to the normal processing.
- iSockInBufSize = iNewTcpWindow;
-
- //Add the usable window to the free window.
- iFreeWindow += iHiddenFreeWindow - iShrinkedWindowSize;
-
- //There are chances that TCP receive window might further shrink.
- iHiddenFreeWindow = 0;
-
- //TCP Receive window shrink phase is over.
- iNewTcpWindow = 0;
-
- //Log this message for information, that Window is shrinked
- LOG(Log::Printf(_L("\ttcp SAP[%u] TCP window shrinking mode off"), (TInt)this));
- }
- }
+ {
+ // Check if we can complete shrinking process
+ if ( aLength > iShrinkedWindowSize )
+ {
+ // We can exit from the shrinking process. Reset variables and
+ // update free window.
+ iFreeWindow = aLength - iShrinkedWindowSize;
+ iShrinkedWindowSize = 0;
+ iNewTcpWindow = 0;
+ }
+ else
+ {
+ // Substract the needed shrinking amount by the amount of bytes client
+ // read from the buffer
+ iShrinkedWindowSize -= aLength;
+ }
+ }
else
#endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW