2401 // |
2407 // |
2402 // Try to retransmit segments. This routine gets called from two places: |
2408 // Try to retransmit segments. This routine gets called from two places: |
2403 // - directly from RetransmitTimeout() |
2409 // - directly from RetransmitTimeout() |
2404 // - from CanSend(), in which case this is a delayed retransmission timeout |
2410 // - from CanSend(), in which case this is a delayed retransmission timeout |
2405 // |
2411 // |
2406 void CProviderTCP6::RetransmitSegments() |
2412 TBool CProviderTCP6::RetransmitSegments() |
2407 { |
2413 { |
2408 ASSERT(iRetransTimer); |
2414 ASSERT(iRetransTimer); |
2409 |
2415 |
2410 LOG(Log::Printf(_L("\ttcp SAP[%u] RetransmitSegments(): queue=%u wnd=%u cwnd=%u, ssthresh=%u dupacks=%d"), |
2416 LOG(Log::Printf(_L("\ttcp SAP[%u] RetransmitSegments(): queue=%u wnd=%u cwnd=%u, ssthresh=%u dupacks=%d"), |
2411 (TInt)this, iSockOutQLen, iSND.WND, iCwnd, iSsthresh, iDupAcks)); |
2417 (TInt)this, iSockOutQLen, iSND.WND, iCwnd, iSsthresh, iDupAcks)); |
2417 iFlags.iRetransmitPending = (iFlow.Status() == EFlow_PENDING); |
2423 iFlags.iRetransmitPending = (iFlow.Status() == EFlow_PENDING); |
2418 if (iFlags.iRetransmitPending) |
2424 if (iFlags.iRetransmitPending) |
2419 { |
2425 { |
2420 LOG(Log::Printf(_L("\ttcp SAP[%u] RetransmitSegments(): Flow pending"), (TInt)this)); |
2426 LOG(Log::Printf(_L("\ttcp SAP[%u] RetransmitSegments(): Flow pending"), (TInt)this)); |
2421 ReSchedRetransmit(); |
2427 ReSchedRetransmit(); |
2422 return; |
2428 return EFalse; |
2423 } |
2429 } |
2424 |
2430 |
2425 // |
2431 // |
2426 // Handle retransmission of data segments and zero window probing. |
2432 // Handle retransmission of data segments and zero window probing. |
2427 // We must have something in output queue. SYN or FIN retransmissions |
2433 // We must have something in output queue. SYN or FIN retransmissions |
2475 // |
2481 // |
2476 // Note 2: We may also end up with iSND.NXT pointing beyond the window if |
2482 // Note 2: We may also end up with iSND.NXT pointing beyond the window if |
2477 // the receiver suddenly shrinks its window. The current solution covers |
2483 // the receiver suddenly shrinks its window. The current solution covers |
2478 // both cases. |
2484 // both cases. |
2479 // |
2485 // |
2480 return; |
2486 return EFalse; |
2481 } |
2487 } |
2482 |
2488 |
2483 // |
2489 // |
2484 // This is a retransmit timout. Do we have anything to do? |
2490 // This is a retransmit timout. Do we have anything to do? |
2485 // |
2491 // |
2486 if (!unacked) |
2492 if (!unacked) |
2487 return; |
2493 return EFalse; |
2488 |
2494 |
2489 LOG(if (iFlags.iFastRetransMode) Log::Printf(_L("\ttcp SAP[%u] RetransmitSegments(): Leaving FAST RETRANS mode"), (TInt)this)); |
2495 LOG(if (iFlags.iFastRetransMode) Log::Printf(_L("\ttcp SAP[%u] RetransmitSegments(): Leaving FAST RETRANS mode"), (TInt)this)); |
2490 iFlags.iFastRetransMode = EFalse; |
2496 iFlags.iFastRetransMode = EFalse; |
2491 iDupAcks = 0; |
2497 iDupAcks = 0; |
2492 |
2498 |
2555 iSendHigh = iTransmitSeq; |
2561 iSendHigh = iTransmitSeq; |
2556 |
2562 |
2557 // If the server doesn't respond because of broken NAT/FW or other, don't keep interface up. |
2563 // If the server doesn't respond because of broken NAT/FW or other, don't keep interface up. |
2558 if (InState(ETcpFinWait1|ETcpClosing|ETcpLastAck)) |
2564 if (InState(ETcpFinWait1|ETcpClosing|ETcpLastAck)) |
2559 DetachIfDead(); |
2565 DetachIfDead(); |
2560 return; |
2566 return EFalse; |
2561 } |
2567 } |
2562 |
2568 |
2563 // |
2569 // |
2564 // Ok, this is either a SYN/FIN retransmit or a TIME-WAIT/FIN-WAIT-2 timeout. |
2570 // Ok, this is either a SYN/FIN retransmit or a TIME-WAIT/FIN-WAIT-2 timeout. |
2565 // |
2571 // |
2566 if (InState(ETcpSynSent)) |
2572 if (InState(ETcpSynSent)) |
2567 { |
2573 { |
2568 // Retransmit SYN |
2574 // Retransmit SYN |
2569 SendSegment(KTcpCtlSYN, iSND.UNA); |
2575 SendSegment(KTcpCtlSYN, iSND.UNA); |
2570 return; |
2576 return EFalse; |
2571 } |
2577 } |
2572 |
2578 |
2573 if (InState(ETcpSynReceived)) |
2579 if (InState(ETcpSynReceived)) |
2574 { |
2580 { |
2575 // Retransmit SYN,ACK |
2581 // Retransmit SYN,ACK |
2576 SendSegment(KTcpCtlSYN|KTcpCtlACK, iSND.UNA); |
2582 SendSegment(KTcpCtlSYN|KTcpCtlACK, iSND.UNA); |
2577 return; |
2583 return EFalse; |
2578 } |
2584 } |
2579 |
2585 |
2580 if (InState(ETcpFinWait1|ETcpClosing|ETcpLastAck)) |
2586 if (InState(ETcpFinWait1|ETcpClosing|ETcpLastAck)) |
2581 { |
2587 { |
2582 // If the server doesn't respond because of broken NAT/FW or other, don't keep interface up. |
2588 // If the server doesn't respond because of broken NAT/FW or other, don't keep interface up. |
2583 |
2589 |
2584 //TSW error:JHAA-82JBNG -- FIN retransmission |
2590 //TSW error:JHAA-82JBNG -- FIN retransmission |
2585 //Depending on the function return value the decision to |
2591 //Depending on the function return value the decision to |
2586 //retransmitt FIN is decided |
2592 //retransmitt FIN is decided |
2587 |
2593 |
2588 TBool continue_send = DetachIfDead(); |
|
2589 // Retransmit FIN |
2594 // Retransmit FIN |
2590 if(continue_send == EFalse) |
2595 if(DetachIfDead()== EFalse) |
|
2596 { |
2591 SendSegment(KTcpCtlFIN|KTcpCtlACK, iSND.UNA); |
2597 SendSegment(KTcpCtlFIN|KTcpCtlACK, iSND.UNA); |
2592 return; |
2598 return EFalse; |
|
2599 } |
2593 } |
2600 } |
2594 |
2601 |
2595 LOG(Log::Printf(_L("\ttcp SAP[%u] RetransmitSegments(): Retransmitter stopping"), (TInt)this)); |
2602 LOG(Log::Printf(_L("\ttcp SAP[%u] RetransmitSegments(): Retransmitter stopping"), (TInt)this)); |
2596 if (!iSockFlags.iAttached) |
2603 if (!iSockFlags.iAttached) |
|
2604 { |
2597 Expire(); |
2605 Expire(); |
2598 return; |
2606 return ETrue; |
|
2607 } |
|
2608 return EFalse; |
2599 } |
2609 } |
2600 |
2610 |
2601 |
2611 |
2602 // |
2612 // |
2603 // Respond to an explicit congestion control signal. |
2613 // Respond to an explicit congestion control signal. |