diff -r bb2423252ea3 -r c1029e558ef5 networkprotocols/tcpipv4v6prt/src/tcp_sap.cpp --- 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