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. |