networkprotocols/tcpipv4v6prt/src/tcp_sap.cpp
changeset 51 78fceed50f62
parent 25 d15a50675083
child 66 34ec136802c5
equal deleted inserted replaced
42:88121cf79045 51:78fceed50f62
  1769 			}
  1769 			}
  1770 
  1770 
  1771 		if (iFlags.iRetransmitPending)
  1771 		if (iFlags.iRetransmitPending)
  1772 			{
  1772 			{
  1773 			iFlags.iRetransmitPending = EFalse;
  1773 			iFlags.iRetransmitPending = EFalse;
  1774 			RetransmitSegments();
  1774 			if(RetransmitSegments())
       
  1775 				return;
  1775 			}
  1776 			}
  1776 
  1777 
  1777 		if (iFlags.iTransmitPending)
  1778 		if (iFlags.iTransmitPending)
  1778 			{
  1779 			{
  1779 			iFlags.iTransmitPending = EFalse;
  1780 			iFlags.iTransmitPending = EFalse;
  2373 		// Exponential backoff.
  2374 		// Exponential backoff.
  2374 		//
  2375 		//
  2375 		++iBackoff;
  2376 		++iBackoff;
  2376 		if (iRTO < Protocol()->MaxRTO())  // Avoid RTO overflow
  2377 		if (iRTO < Protocol()->MaxRTO())  // Avoid RTO overflow
  2377 			ResetRTO();
  2378 			ResetRTO();
  2378 
  2379 		
       
  2380 		if(DetachIfDead())
       
  2381 			{
       
  2382 			Expire();
       
  2383 			return;
       
  2384 			}
  2379 		//
  2385 		//
  2380 		// Timeout?
  2386 		// Timeout?
  2381 		//
  2387 		//
  2382 		// Note: we time out if this is a connect attempt or a retransmission,
  2388 		// Note: we time out if this is a connect attempt or a retransmission,
  2383 		// but we must not time out if we're probing a zero window.
  2389 		// but we must not time out if we're probing a zero window.
  2488 //
  2494 //
  2489 // Try to retransmit segments. This routine gets called from two places:
  2495 // Try to retransmit segments. This routine gets called from two places:
  2490 //  - directly from RetransmitTimeout()
  2496 //  - directly from RetransmitTimeout()
  2491 //  - from CanSend(), in which case this is a delayed retransmission timeout
  2497 //  - from CanSend(), in which case this is a delayed retransmission timeout
  2492 //
  2498 //
  2493 void CProviderTCP6::RetransmitSegments()
  2499 TBool CProviderTCP6::RetransmitSegments()
  2494 	{
  2500 	{
  2495 	ASSERT(iRetransTimer);
  2501 	ASSERT(iRetransTimer);
  2496 
  2502 
  2497 	LOG(Log::Printf(_L("\ttcp SAP[%u] RetransmitSegments(): queue=%u wnd=%u cwnd=%u, ssthresh=%u dupacks=%d"),
  2503 	LOG(Log::Printf(_L("\ttcp SAP[%u] RetransmitSegments(): queue=%u wnd=%u cwnd=%u, ssthresh=%u dupacks=%d"),
  2498 		(TInt)this, iSockOutQLen, iSND.WND, iCwnd, iSsthresh, iDupAcks));
  2504 		(TInt)this, iSockOutQLen, iSND.WND, iCwnd, iSsthresh, iDupAcks));
  2504 	iFlags.iRetransmitPending = (iFlow.Status() == EFlow_PENDING);
  2510 	iFlags.iRetransmitPending = (iFlow.Status() == EFlow_PENDING);
  2505 	if (iFlags.iRetransmitPending)
  2511 	if (iFlags.iRetransmitPending)
  2506 		{
  2512 		{
  2507 		LOG(Log::Printf(_L("\ttcp SAP[%u] RetransmitSegments(): Flow pending"), (TInt)this));
  2513 		LOG(Log::Printf(_L("\ttcp SAP[%u] RetransmitSegments(): Flow pending"), (TInt)this));
  2508 		ReSchedRetransmit();
  2514 		ReSchedRetransmit();
  2509 		return;
  2515 		return EFalse;
  2510 		}
  2516 		}
  2511 
  2517 
  2512 	//
  2518 	//
  2513 	// Handle retransmission of data segments and zero window probing.
  2519 	// Handle retransmission of data segments and zero window probing.
  2514 	// We must have something in output queue. SYN or FIN retransmissions
  2520 	// We must have something in output queue. SYN or FIN retransmissions
  2562 			//
  2568 			//
  2563 			// Note 2: We may also end up with iSND.NXT pointing beyond the window if
  2569 			// Note 2: We may also end up with iSND.NXT pointing beyond the window if
  2564 			// the receiver suddenly shrinks its window. The current solution covers
  2570 			// the receiver suddenly shrinks its window. The current solution covers
  2565 			// both cases.
  2571 			// both cases.
  2566 			//
  2572 			//
  2567 			return;
  2573 			return EFalse;
  2568 			}
  2574 			}
  2569 
  2575 
  2570 		//
  2576 		//
  2571 		// This is a retransmit timout. Do we have anything to do?
  2577 		// This is a retransmit timout. Do we have anything to do?
  2572 		//
  2578 		//
  2573 		if (!unacked)
  2579 		if (!unacked)
  2574 			return;
  2580 			return EFalse;
  2575 
  2581 
  2576 		LOG(if (iFlags.iFastRetransMode) Log::Printf(_L("\ttcp SAP[%u] RetransmitSegments(): Leaving FAST RETRANS mode"), (TInt)this));
  2582 		LOG(if (iFlags.iFastRetransMode) Log::Printf(_L("\ttcp SAP[%u] RetransmitSegments(): Leaving FAST RETRANS mode"), (TInt)this));
  2577 		iFlags.iFastRetransMode = EFalse;
  2583 		iFlags.iFastRetransMode = EFalse;
  2578 		iDupAcks = 0;
  2584 		iDupAcks = 0;
  2579 
  2585 
  2642 			iSendHigh = iTransmitSeq;
  2648 			iSendHigh = iTransmitSeq;
  2643 
  2649 
  2644 		// If the server doesn't respond because of broken NAT/FW or other, don't keep interface up.
  2650 		// If the server doesn't respond because of broken NAT/FW or other, don't keep interface up.
  2645 		if (InState(ETcpFinWait1|ETcpClosing|ETcpLastAck))
  2651 		if (InState(ETcpFinWait1|ETcpClosing|ETcpLastAck))
  2646 			DetachIfDead();
  2652 			DetachIfDead();
  2647 		return;
  2653 		return EFalse;
  2648 		}
  2654 		}
  2649 
  2655 
  2650 	//
  2656 	//
  2651 	// Ok, this is either a SYN/FIN retransmit or a TIME-WAIT/FIN-WAIT-2 timeout.
  2657 	// Ok, this is either a SYN/FIN retransmit or a TIME-WAIT/FIN-WAIT-2 timeout.
  2652 	//
  2658 	//
  2653 	if (InState(ETcpSynSent))
  2659 	if (InState(ETcpSynSent))
  2654 		{
  2660 		{
  2655 		// Retransmit SYN
  2661 		// Retransmit SYN
  2656 		SendSegment(KTcpCtlSYN, iSND.UNA);
  2662 		SendSegment(KTcpCtlSYN, iSND.UNA);
  2657 		return;
  2663 		return EFalse;
  2658 		}
  2664 		}
  2659 
  2665 
  2660 	if (InState(ETcpSynReceived))
  2666 	if (InState(ETcpSynReceived))
  2661 		{
  2667 		{
  2662 		// Retransmit SYN,ACK
  2668 		// Retransmit SYN,ACK
  2663 		SendSegment(KTcpCtlSYN|KTcpCtlACK, iSND.UNA);
  2669 		SendSegment(KTcpCtlSYN|KTcpCtlACK, iSND.UNA);
  2664 		return;
  2670 		return EFalse;
  2665 		}
  2671 		}
  2666 
  2672 
  2667 	if (InState(ETcpFinWait1|ETcpClosing|ETcpLastAck))
  2673 	if (InState(ETcpFinWait1|ETcpClosing|ETcpLastAck))
  2668 		{
  2674 		{
  2669 		// If the server doesn't respond because of broken NAT/FW or other, don't keep interface up.
  2675 		// If the server doesn't respond because of broken NAT/FW or other, don't keep interface up.
  2670 	
  2676 	
  2671 	    //TSW error:JHAA-82JBNG -- FIN retransmission 
  2677 	    //TSW error:JHAA-82JBNG -- FIN retransmission 
  2672 		//Depending on the function return value the decision to
  2678 		//Depending on the function return value the decision to
  2673 	    //retransmitt FIN is decided
  2679 	    //retransmitt FIN is decided
  2674 
  2680 	
  2675 		TBool continue_send = DetachIfDead();
       
  2676 		// Retransmit FIN
  2681 		// Retransmit FIN
  2677 		if(continue_send == EFalse)
  2682 		if(DetachIfDead()== EFalse)
       
  2683 			{
  2678 			SendSegment(KTcpCtlFIN|KTcpCtlACK, iSND.UNA);
  2684 			SendSegment(KTcpCtlFIN|KTcpCtlACK, iSND.UNA);
  2679 		return;
  2685 			return EFalse;
       
  2686 			}
  2680 		}
  2687 		}
  2681 
  2688 
  2682 	LOG(Log::Printf(_L("\ttcp SAP[%u] RetransmitSegments(): Retransmitter stopping"), (TInt)this));
  2689 	LOG(Log::Printf(_L("\ttcp SAP[%u] RetransmitSegments(): Retransmitter stopping"), (TInt)this));
  2683 	if (!iSockFlags.iAttached)
  2690 	if (!iSockFlags.iAttached)
       
  2691 		{
  2684 		Expire();
  2692 		Expire();
  2685 	return;
  2693 		return ETrue;
       
  2694 		}
       
  2695 	return EFalse;
  2686 	}
  2696 	}
  2687 
  2697 
  2688 
  2698 
  2689 //
  2699 //
  2690 // Respond to an explicit congestion control signal.
  2700 // Respond to an explicit congestion control signal.