networkprotocols/tcpipv4v6prt/src/tcp_sap.cpp
branchGCC_SURGE
changeset 46 73696f712f10
parent 25 d15a50675083
child 51 78fceed50f62
equal deleted inserted replaced
34:b433d36685ef 46:73696f712f10
   258 
   258 
   259 	iDelayAckTimer->InitL();
   259 	iDelayAckTimer->InitL();
   260 	iRetransTimer->InitL();
   260 	iRetransTimer->InitL();
   261 	iLingerTimer->InitL();
   261 	iLingerTimer->InitL();
   262 	iSockInBufSize        = Protocol()->RecvBuf();
   262 	iSockInBufSize        = Protocol()->RecvBuf();
       
   263 #ifdef SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
       
   264 	if(iSockInBufSize == Protocol()->RecvBufFromIniFile())
       
   265 	    iSocketStartupCase = ETrue;
       
   266 	else
       
   267 	    iSocketStartupCase = EFalse;
       
   268 #endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW    	
       
   269 	
   263 	iSockOutBufSize       = Protocol()->SendBuf();
   270 	iSockOutBufSize       = Protocol()->SendBuf();
   264 	iSsthresh		= KMaxTInt32;
   271 	iSsthresh		= KMaxTInt32;
   265 	iRTO			= Protocol()->InitialRTO();
   272 	iRTO			= Protocol()->InitialRTO();
   266 	ClearRTT();
   273 	ClearRTT();
   267 	iMSS                  = Protocol()->MSS();
   274 	iMSS                  = Protocol()->MSS();
   617 		        ret = KErrLocked;
   624 		        ret = KErrLocked;
   618             else if (intValue < STATIC_CAST(TInt, KTcpMinimumWindow))
   625             else if (intValue < STATIC_CAST(TInt, KTcpMinimumWindow))
   619                 iSockInBufSize = KTcpMinimumWindow;
   626                 iSockInBufSize = KTcpMinimumWindow;
   620             else
   627             else
   621                 {
   628                 {
   622 
   629                 //If its the startup case, then there should be no algorithm used to shrink
   623 		        //If new TCP window is larger then the previous window, increase the 
   630 				//or expand the window size from the default value provided in the ini file
   624 		        //iSockInBufSize right now. TCP recv function takes  care of
   631                 //the new value should be set directly
   625 		        //advertising a new effective TCP window. 
   632                 if(iSocketStartupCase)
   626 		            if (intValue >= iSockInBufSize)
   633                     {
   627 		                {
   634 					//Add the extra window to free window pool
   628 		                //Make it Zero so TCP could avoid the
   635 					//if the window being set is greater than what is specified in ini file (startup case), then just overwrite the new window.
   629 		                //TCP window shrinking processing in Recv.  
   636 					//Add difference to free window
   630 		                iNewTcpWindow = 0;
   637 					//else set free window to zero
   631 		                //FreeWindow has to be increased at the same time.
   638 					if(intValue > iSockInBufSize)
   632 		                iFreeWindow += intValue - iSockInBufSize;
   639 						iFreeWindow += intValue - iSockInBufSize;
   633 		                // Make the new TCP receive buffer change effective now.
   640 					else
   634 		                iSockInBufSize = intValue;                                                          
   641 						iFreeWindow = 0;
   635 		                }
   642 					//set the buffer
   636 		            else
   643                     iSockInBufSize = intValue;
   637 		                {
   644 					//disable startup flag.
   638 		                //This sets iNewTcpWindow to a non-zero value, which indicates 
   645                     iSocketStartupCase = EFalse;
   639 		                //to the TCP that window is shrunk and process TCP segments
   646                     }
   640 		                //which are in air before setting a new TCP receive buffer.         
   647                 else 
   641 		                //TCP Receive window starts moving only when TCP hidden window
   648                 {
   642 		                //size exceeds the size of the shrunk window.
   649 					// Check for minimum value
   643 		                   
   650 	                if (intValue < STATIC_CAST(TInt, KTcpMinimumWindow))
   644 		                iNewTcpWindow = intValue;
   651 	                    {
   645 		                //Even in case of window shrink we can set the receive buffer size
   652 	                    intValue = STATIC_CAST(TInt, KTcpMinimumWindow);
   646 		                //immediately. This will be helpful, for processing SYN-ACK and other
   653 	                    }
   647 		                //receiver side processing.
   654 	                // Handle the situation where the connection has been established and 
   648 		                //For already connected sockets iNewTcpWindow will be taking care
   655 	                // window scaling is not in use
   649 		                //of shrinking the window size for that TCP session.
   656 	                if ( InState( ETcpSynReceived | ETcpEstablished ) && !iRcvWscale )
   650 		                iSockInBufSize = iNewTcpWindow;
   657 	                    {
   651 		                if( iAdvertisedWindow > iNewTcpWindow )
   658 	                    // Do not allow window sizes larger than 0xFFFF
   652 		                    {
   659 	                    intValue = Min ( intValue, 0xFFFF );
   653 		                    iShrinkedWindowSize = iAdvertisedWindow - iNewTcpWindow;
   660 	                    }
   654 		                    }
   661 
   655 		                else
   662 	                // Check whether we are increasing or decreasing window size
   656 		                    {
   663 	                if ( intValue >= iSockInBufSize )
   657 		                    // No Need to process TCP receive window processing.
   664 	                    {
   658 		                    iNewTcpWindow = 0;
   665 	                    // New window is larger than current one, check if a
   659 		                    }
   666 	                    // shrinking process is active
   660 		                }
   667 	                    if ( !iNewTcpWindow )
   661 					
   668 	                        {
   662                 } 
   669 	                        // Mark new "space" as free, it will be updated to
   663 
   670 	                        // peer on next operation.
       
   671 	                        iFreeWindow += intValue - iSockInBufSize;
       
   672 	                        }
       
   673 	                    else
       
   674 	                        {
       
   675 	                        // In the middle of shrinking process.
       
   676                       if ( iShrinkedWindowSize <= ( intValue - iSockInBufSize ))
       
   677 	                            {
       
   678 	                            // Increment to window size is enough to complete
       
   679 	                            // shrinking process. Update variables and exit
       
   680 	                            // from shrinking process.
       
   681                           iFreeWindow = ( intValue - iSockInBufSize ) - iShrinkedWindowSize;
       
   682 	                            iShrinkedWindowSize = 0;
       
   683 	                            iNewTcpWindow = 0;
       
   684 	                            }
       
   685 	                        else
       
   686 	                            {
       
   687 	                            // Not quite there yet but closer. Less to shrink,
       
   688 	                            // update this, but do not exit from shrinking
       
   689 	                            // process
       
   690                           iShrinkedWindowSize -= intValue - iSockInBufSize;
       
   691 	                            iNewTcpWindow = intValue;
       
   692 	                            }
       
   693 	                        }
       
   694 	                    }
       
   695 	                else
       
   696 	                    {
       
   697 	                    // Requested window is smaller than current one. Start or
       
   698 	                    // continue shrinking process. RCV window can be occupied
       
   699 	                    // for two different purpose at the moment
       
   700 	                    // 1. Client data in iSockInQ not read by application
       
   701 	                    // 2. Free window "opened" to peer (iAdvertisedWindow)
       
   702 	                    // When shrinking, we must ensure that when reopening
       
   703 	                    // the window to client there must be truly empty space
       
   704 	                    // in the window. Thus, freeze the right edge of the
       
   705 	                    // window (iRCV.NXT + iRCV.WND stays constant) until
       
   706 	                    // shrinking is completed.
       
   707 	                
       
   708 	                    if ( iNewTcpWindow )
       
   709 	                        {
       
   710 	                        // There is an ongoing shrink process, add the
       
   711 	                        // change to the amount to be shrinked
       
   712 	                        iShrinkedWindowSize += iSockInBufSize - intValue;
       
   713 	                        iNewTcpWindow = intValue;
       
   714 	                        }
       
   715 	                    else
       
   716 	                        {
       
   717 	                        // This is a new shrinking process, count how much
       
   718 	                        // needs to be shrinked
       
   719                       iShrinkedWindowSize = iSockInQLen + iRCV.WND;
       
   720 	                        if ( iShrinkedWindowSize >= intValue )
       
   721 	                            {
       
   722 	                            // We need to shrink since the currently occupied
       
   723 	                            // window does not fit to new one
       
   724 	                            iShrinkedWindowSize -= intValue;
       
   725 	                            // There is now free space in the window
       
   726 	                            iFreeWindow = 0;
       
   727 	                            // iNewTcpWindow is used as a state variable for
       
   728 	                            // shrinking
       
   729 	                            iNewTcpWindow = intValue;
       
   730 	                            }
       
   731 	                        else
       
   732 	                            {
       
   733 	                            // No need to shrink since we can fit the current
       
   734 	                            // contents to the new window, update free window
       
   735 	                            // If TCP connection is not yet setup, the free
       
   736 	                            // window will be updated on connection setup, 
       
   737 	                            // for existing connection it will be used
       
   738 	                            // next time application reads data
       
   739 	                            if ( iFreeWindow >= ( iSockInBufSize - intValue ))
       
   740 	                                {
       
   741 	                                iFreeWindow -= iSockInBufSize - intValue;
       
   742 	                                }
       
   743 	                            else 
       
   744 	                                {
       
   745 	                                // Something wrong. Try to reevaluate...
       
   746 	                                iFreeWindow = intValue - iShrinkedWindowSize;
       
   747 	                                }
       
   748 	                            iShrinkedWindowSize = 0;
       
   749 	                            }
       
   750 	                        }
       
   751 	                    }
       
   752 	                // Even in case of window shrink we can set the receive buffer size
       
   753 	                // immediately. This will be helpful, for processing SYN-ACK and other
       
   754 	                // receiver side processing.
       
   755 	                // For already connected sockets iNewTcpWindow will be taking care
       
   756 	                // of shrinking the window size for that TCP session.
       
   757 	                iSockInBufSize = intValue;
       
   758 	                }
       
   759 	            } 
   664 		    }
   760 		    }
   665 		    break;
   761 		    break;
   666 #endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
   762 #endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
   667 			case KSoTcpRecvWinSize:
   763 			case KSoTcpRecvWinSize:
   668 			    {
   764 			    {
  1360 	//We need to make sure, that we will show that window is not shrinked
  1456 	//We need to make sure, that we will show that window is not shrinked
  1361 	//to the sender, so tha right edge of the sender window remains constant.
  1457 	//to the sender, so tha right edge of the sender window remains constant.
  1362 	//if This is true, then it is a case of TCP window shrink and we need 
  1458 	//if This is true, then it is a case of TCP window shrink and we need 
  1363 	//to handle it.
  1459 	//to handle it.
  1364 	if ( iNewTcpWindow )
  1460 	if ( iNewTcpWindow )
  1365 		{
  1461 	    {
  1366 	   	//Log  this message for information, that Window is shrinked
  1462 	    // Check if we can complete shrinking process
  1367 	   	LOG(Log::Printf(_L("\ttcp SAP[%u] TCP window shrinking mode on"), (TInt)this));
  1463 	    if ( aLength > iShrinkedWindowSize )
  1368 	   
  1464 	        {
  1369 	   	//Increase the hidden free TCP receive window.
  1465 	        // We can exit from the shrinking process. Reset variables and
  1370 	   	iHiddenFreeWindow += aLength;
  1466 	        // update free window.
  1371 	   
  1467 	        iFreeWindow = aLength - iShrinkedWindowSize;
  1372 	   	if (iHiddenFreeWindow >= iShrinkedWindowSize)
  1468 	        iShrinkedWindowSize = 0;
  1373 			{
  1469 	        iNewTcpWindow = 0;
  1374 			//Disable window shrink processing, so that TCP could switch
  1470 	        }
  1375 			//to the normal processing.    
  1471 	    else
  1376 			iSockInBufSize = iNewTcpWindow;
  1472 	        {
  1377 			
  1473 	        // Substract the needed shrinking amount by the amount of bytes client
  1378 			//Add the usable window to the free window.
  1474 	        // read from the buffer
  1379 			iFreeWindow += iHiddenFreeWindow - iShrinkedWindowSize;
  1475 	        iShrinkedWindowSize -= aLength;
  1380 			
  1476 	        }
  1381 			//There are chances that TCP receive window might further shrink.
  1477 	    }
  1382 			iHiddenFreeWindow = 0;
       
  1383 			
       
  1384 			//TCP Receive window shrink phase is over.
       
  1385 			iNewTcpWindow = 0;
       
  1386 			
       
  1387 			//Log  this message for information, that Window is shrinked
       
  1388 			LOG(Log::Printf(_L("\ttcp SAP[%u] TCP window shrinking mode off"), (TInt)this));
       
  1389 			}
       
  1390 		}
       
  1391 	else
  1478 	else
  1392 #endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
  1479 #endif //SYMBIAN_ADAPTIVE_TCP_RECEIVE_WINDOW
  1393 	
  1480 	
  1394 		{
  1481 		{
  1395 		iFreeWindow += aLength;	
  1482 		iFreeWindow += aLength;