--- a/networkprotocols/tcpipv4v6prt/src/tcp_sap.cpp Wed Sep 15 13:53:10 2010 +0300
+++ b/networkprotocols/tcpipv4v6prt/src/tcp_sap.cpp Wed Oct 13 16:17:27 2010 +0300
@@ -141,7 +141,7 @@
//
//The below is UID of the client(http client) using this option. We are not exposing this right now...
-const TUint32 KSoTcpLingerinMicroSec = 0x101F55F6;
+const TUint32 TSoTcpLingerinMicroSec = 0x101F55F6;
#ifdef _LOG
const TText *CProviderTCP6::TcpState(TUint aState)
{
@@ -261,13 +261,6 @@
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();
@@ -627,137 +620,48 @@
iSockInBufSize = KTcpMinimumWindow;
else
{
- //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;
- }
- }
+
+ //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;
+ }
+ }
+
+ }
+
}
break;
#endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
@@ -792,11 +696,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 TSoTcpLingerinMicroSec:
+ 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))
{
@@ -1200,11 +1104,9 @@
}
else
{
- //
- // Start linger timer. RSocket::Close() returns when timer
- // expires or when all data has been succesfully transmitted.
- //
- if(iMicroSecCalcFlag)
+ // Start linger timer. RSocket::Close() returns when timer
+ // expires or when all data has been succesfully transmitted.
+ 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
@@ -1213,7 +1115,7 @@
else
{
iLingerTimer->Start(iLinger * KOneSecondInUs);
- }
+ }
}
SchedTransmit();
@@ -1473,23 +1375,32 @@
//if This is true, then it is a case of TCP window shrink and we need
//to handle it.
if ( iNewTcpWindow )
- {
- // 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;
- }
- }
+ {
+ //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));
+ }
+ }
else
#endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW