networkprotocols/tcpipv4v6prt/src/tcp_sap.cpp
branchRCL_3
changeset 23 23b59305592d
parent 12 e9cc36e353d4
child 40 d566d76acea1
equal deleted inserted replaced
21:2129f10626ba 23:23b59305592d
  1100 			{
  1100 			{
  1101 			//
  1101 			//
  1102 			// Start linger timer. RSocket::Close() returns when timer
  1102 			// Start linger timer. RSocket::Close() returns when timer
  1103 			// expires or when all data has been succesfully transmitted.
  1103 			// expires or when all data has been succesfully transmitted.
  1104 			//
  1104 			//
  1105 			iLingerTimer->Start(iLinger * KOneSecondUs);
  1105 			iLingerTimer->Start(iLinger * KOneSecondInUs);
  1106 			}
  1106 			}
  1107 		SchedTransmit();
  1107 		SchedTransmit();
  1108 
  1108 
  1109 		break;
  1109 		break;
  1110 
  1110 
  1698 			
  1698 			
  1699 		if (CanTriggerKeepAlive())
  1699 		if (CanTriggerKeepAlive())
  1700 			{
  1700 			{
  1701 			// The heaviest time check only if we are otherwise allowed to send the keepalive.
  1701 			// The heaviest time check only if we are otherwise allowed to send the keepalive.
  1702 			TUint32 time_now = TimeStamp();
  1702 			TUint32 time_now = TimeStamp();
  1703 			if (time_now - iLastTriggeredKeepAlive > KTcpKeepAliveTH * KOneSecondUs)
  1703 			if (time_now - iLastTriggeredKeepAlive > KTcpKeepAliveTH * KOneSecondInMs)
  1704 				{
  1704 				{
  1705 				iLastTriggeredKeepAlive = time_now;
  1705 				iLastTriggeredKeepAlive = time_now;
  1706 				LOG(Log::Printf(_L("\ttcp SAP[%u] CanSend(): Sending a Keep-Alive probe"), (TInt)this));
  1706 				LOG(Log::Printf(_L("\ttcp SAP[%u] CanSend(): Sending a Keep-Alive probe"), (TInt)this));
  1707 				SendSegment(KTcpCtlACK, iSND.UNA - 1, 0);
  1707 				SendSegment(KTcpCtlACK, iSND.UNA - 1, 0);
  1708 				}
  1708 				}
  2352 	TUint32 usec = TimeStamp();
  2352 	TUint32 usec = TimeStamp();
  2353 
  2353 
  2354 	if (!iLastTimeout)
  2354 	if (!iLastTimeout)
  2355 		iLastTimeout = usec;
  2355 		iLastTimeout = usec;
  2356 
  2356 
  2357 	TUint32 distance = (usec - iLastTimeout) / KOneSecondUs;  // seconds
  2357 	TUint32 distance = (usec - iLastTimeout) / KOneSecondInMs;  // seconds
  2358 	TUint32 interval = iBackoff ? Protocol()->KeepAliveRxmt() : Protocol()->KeepAliveIntv();
  2358 	TUint32 interval = iBackoff ? Protocol()->KeepAliveRxmt() : Protocol()->KeepAliveIntv();
  2359 
  2359 
  2360 	if (distance > interval)
  2360 	if (distance > interval)
  2361 		{
  2361 		{
  2362 		// Send a keepalive probe. If no ack arrives, next one is sent after a shorter time (75 s)
  2362 		// Send a keepalive probe. If no ack arrives, next one is sent after a shorter time (75 s)
  2363 		LOG(Log::Printf(_L("\ttcp SAP[%u] KeepAliveTimeout(): Sending a Keep-Alive probe"), (TInt)this));
  2363 		LOG(Log::Printf(_L("\ttcp SAP[%u] KeepAliveTimeout(): Sending a Keep-Alive probe"), (TInt)this));
  2364 		SendSegment(KTcpCtlACK, iSND.UNA - 1, 0);
  2364 		SendSegment(KTcpCtlACK, iSND.UNA - 1, 0);
  2365 		iBackoff++;
  2365 		iBackoff++;
  2366 		iRetransTimer->Restart(Protocol()->KeepAliveRxmt() * KOneSecondUs);
  2366 		iRetransTimer->Restart(Protocol()->KeepAliveRxmt() * KOneSecondInUs);
  2367 		}
  2367 		}
  2368 	else
  2368 	else
  2369 		{
  2369 		{
  2370 		// This branch is entered when the first keepalive has to be issued after an idle period.
  2370 		// This branch is entered when the first keepalive has to be issued after an idle period.
  2371 		distance = Protocol()->KeepAliveIntv() - distance;
  2371 		distance = Protocol()->KeepAliveIntv() - distance;
  2372 		iRetransTimer->Restart((distance > 1800) ?
  2372 		iRetransTimer->Restart((distance > 1800) ?
  2373 			1800 * KOneSecondUs : (distance * KOneSecondUs));
  2373 			1800 * KOneSecondInUs : (distance * KOneSecondInUs));
  2374 		}
  2374 		}
  2375 	}
  2375 	}
  2376 
  2376 
  2377 
  2377 
  2378 void CProviderTCP6::ResetKeepAlives()
  2378 void CProviderTCP6::ResetKeepAlives()
  2379 	{
  2379 	{
  2380 	ASSERT(iRetransTimer);
  2380 	ASSERT(iRetransTimer);
  2381 	iRetransTimer->Restart((Protocol()->KeepAliveIntv() > 1800) ?
  2381 	iRetransTimer->Restart((Protocol()->KeepAliveIntv() > 1800) ?
  2382 		1800 * KOneSecondUs : (Protocol()->KeepAliveIntv() * KOneSecondUs));
  2382 		1800 * KOneSecondInUs : (Protocol()->KeepAliveIntv() * KOneSecondInUs));
  2383 	// Backoff is used for counting unacknowledged keepalive retransmissions during idle periods
  2383 	// Backoff is used for counting unacknowledged keepalive retransmissions during idle periods
  2384 	iBackoff = 0;
  2384 	iBackoff = 0;
  2385 	iLastTimeout = TimeStamp();
  2385 	iLastTimeout = TimeStamp();
  2386 	}
  2386 	}
  2387 
  2387 
  3589 							}
  3589 							}
  3590 						else if (!iFlags.iSackOk)
  3590 						else if (!iFlags.iSackOk)
  3591 							{
  3591 							{
  3592 							// NewReno partial ACK processing.
  3592 							// NewReno partial ACK processing.
  3593 
  3593 
  3594 			  /* From RFC2582:
  3594 						  /* From RFC2582:
  3595 			   If this ACK does *not* acknowledge all of the data up to and
  3595 						   If this ACK does *not* acknowledge all of the data up to and
  3596 			   including "recover", then this is a partial ACK.  In this case,
  3596 						   including "recover", then this is a partial ACK.  In this case,
  3597 			   retransmit the first unacknowledged segment.  Deflate the
  3597 						   retransmit the first unacknowledged segment.  Deflate the
  3598 			   congestion window by the amount of new data acknowledged, then
  3598 						   congestion window by the amount of new data acknowledged, then
  3599 			   add back one MSS and send a new segment if permitted by the new
  3599 						   add back one MSS and send a new segment if permitted by the new
  3600 			   value of cwnd.  This "partial window deflation" attempts to
  3600 						   value of cwnd.  This "partial window deflation" attempts to
  3601 			   ensure that, when Fast Recovery eventually ends, approximately
  3601 						   ensure that, when Fast Recovery eventually ends, approximately
  3602 			   ssthresh amount of data will be outstanding in the network.  Do
  3602 						   ssthresh amount of data will be outstanding in the network.  Do
  3603 			   not exit the Fast Recovery procedure (i.e., if any duplicate ACKs
  3603 						   not exit the Fast Recovery procedure (i.e., if any duplicate ACKs
  3604 			   subsequently arrive, execute Steps 3 and 4 above).
  3604 						   subsequently arrive, execute Steps 3 and 4 above).
  3605 
  3605 
  3606 			   For the first partial ACK that arrives during Fast Recovery, also
  3606 						   For the first partial ACK that arrives during Fast Recovery, also
  3607 			   reset the retransmit timer.
  3607 						   reset the retransmit timer.
  3608 							*/
  3608 							*/
  3609 
  3609 
  3610 							iCwnd -= acked;
  3610 							iCwnd -= acked;
  3611 							iCwnd += iSMSS;
  3611 							iCwnd += iSMSS;
  3612 							LOG(Log::Printf(_L("\ttcp SAP[%u] ProcessSegments(): FAST RETRANSMIT on PARTIAL ACK"), (TInt)this));
  3612 							LOG(Log::Printf(_L("\ttcp SAP[%u] ProcessSegments(): FAST RETRANSMIT on PARTIAL ACK"), (TInt)this));
  3619 							//
  3619 							//
  3620 							ASSERT(iSMSS);
  3620 							ASSERT(iSMSS);
  3621 							iDupAcks = Max(iDupAcks - acked / (TInt)iSMSS, 0);
  3621 							iDupAcks = Max(iDupAcks - acked / (TInt)iSMSS, 0);
  3622 							}
  3622 							}
  3623 						}
  3623 						}
       
  3624 					else if ( iDupAcks )
       
  3625                         {
       
  3626                         // New data acknowledged, and not ongoing any recovery action
       
  3627                         // Reset duplicate ack count
       
  3628                         LOG(Log::Printf(_L("\ttcp SAP[%u] ProcessSegments(): Reset iDupAcks to 0"), (TInt)this));
       
  3629                         iDupAcks = 0;
       
  3630                         }
  3624 
  3631 
  3625 					// Reset limited transmit window
  3632 					// Reset limited transmit window
  3626 					iLwnd = 0;
  3633 					iLwnd = 0;
  3627 
  3634 
  3628 					// Everything acked?
  3635 					// Everything acked?
  3794 					if (SourceQuench() || iQuenchSeq.Outside(iSND.NXT, iSND.NXT + iSND.WND))
  3801 					if (SourceQuench() || iQuenchSeq.Outside(iSND.NXT, iSND.NXT + iSND.WND))
  3795 						{
  3802 						{
  3796 						iFlags.iEcnSendCWR = ETrue;
  3803 						iFlags.iEcnSendCWR = ETrue;
  3797 						}
  3804 						}
  3798 					}
  3805 					}
  3799 				if((iSND.NXT - ack) >0 && InState(ETcpEstablished) && (acked ==0))
  3806 				// This section used to hold the RetryACK concept, a reference can be checked
  3800 					{
  3807 				// from older versions(9.2/9.3). Its being removed as not required.	
  3801 					iRetryAck++;
       
  3802 					if(iRetryAck >=4) // 4 an arbitary number; as this count does not refer to dup_ack, this will not interfere with Fast retransmission
       
  3803 						{
       
  3804 						LOG(Log::Printf(_L("\ttcp SAP[%u] ProcessSegments(): retransmitting the segment"), (TInt)this));
       
  3805 						SendSegments(ETrue);
       
  3806 						iRetryAck = 0; // reset the retry count
       
  3807 						}
       
  3808 					}
       
  3809 					
  3808 					
  3810 				}
  3809 				}
  3811 			}
  3810 			}
  3812 
  3811 
  3813 		//
  3812 		//