138 // including the establishment of security and mobility bindings. CONNECT is |
138 // including the establishment of security and mobility bindings. CONNECT is |
139 // specific to this TCP implementation and is therefore not visible in the |
139 // specific to this TCP implementation and is therefore not visible in the |
140 // state chart above. It would be located between CLOSED and SYN-SENT. |
140 // state chart above. It would be located between CLOSED and SYN-SENT. |
141 // |
141 // |
142 |
142 |
143 |
143 //The below is UID of the client(http client) using this option. We are not exposing this right now... |
|
144 const TUint32 KSoTcpLingerinMicroSec = 0x101F55F6; |
144 #ifdef _LOG |
145 #ifdef _LOG |
145 const TText *CProviderTCP6::TcpState(TUint aState) |
146 const TText *CProviderTCP6::TcpState(TUint aState) |
146 { |
147 { |
147 TInt i; |
148 TInt i; |
148 static const TText* const tcpStates[] = { |
149 static const TText* const tcpStates[] = { |
1196 { |
1202 { |
1197 // |
1203 // |
1198 // Start linger timer. RSocket::Close() returns when timer |
1204 // Start linger timer. RSocket::Close() returns when timer |
1199 // expires or when all data has been succesfully transmitted. |
1205 // expires or when all data has been succesfully transmitted. |
1200 // |
1206 // |
1201 iLingerTimer->Start(iLinger * KOneSecondUs); |
1207 if(iMicroSecCalcFlag) |
|
1208 { |
|
1209 //expecting iLinger timer to be specified in microsec.This will be set currently by browser where in |
|
1210 //it is expected to be close with in certian time |
|
1211 iLingerTimer->Start(iLinger * 1); |
|
1212 } |
|
1213 else |
|
1214 { |
|
1215 iLingerTimer->Start(iLinger * KOneSecondInUs); |
|
1216 } |
1202 } |
1217 } |
1203 SchedTransmit(); |
1218 SchedTransmit(); |
1204 |
1219 |
1205 break; |
1220 break; |
1206 |
1221 |
1786 |
1801 |
1787 if (CanTriggerKeepAlive()) |
1802 if (CanTriggerKeepAlive()) |
1788 { |
1803 { |
1789 // The heaviest time check only if we are otherwise allowed to send the keepalive. |
1804 // The heaviest time check only if we are otherwise allowed to send the keepalive. |
1790 TUint32 time_now = TimeStamp(); |
1805 TUint32 time_now = TimeStamp(); |
1791 if (time_now - iLastTriggeredKeepAlive > KTcpKeepAliveTH * KOneSecondUs) |
1806 if (time_now - iLastTriggeredKeepAlive > KTcpKeepAliveTH * KOneSecondInMs) |
1792 { |
1807 { |
1793 iLastTriggeredKeepAlive = time_now; |
1808 iLastTriggeredKeepAlive = time_now; |
1794 LOG(Log::Printf(_L("\ttcp SAP[%u] CanSend(): Sending a Keep-Alive probe"), (TInt)this)); |
1809 LOG(Log::Printf(_L("\ttcp SAP[%u] CanSend(): Sending a Keep-Alive probe"), (TInt)this)); |
1795 SendSegment(KTcpCtlACK, iSND.UNA - 1, 0); |
1810 SendSegment(KTcpCtlACK, iSND.UNA - 1, 0); |
1796 } |
1811 } |
2445 TUint32 usec = TimeStamp(); |
2460 TUint32 usec = TimeStamp(); |
2446 |
2461 |
2447 if (!iLastTimeout) |
2462 if (!iLastTimeout) |
2448 iLastTimeout = usec; |
2463 iLastTimeout = usec; |
2449 |
2464 |
2450 TUint32 distance = (usec - iLastTimeout) / KOneSecondUs; // seconds |
2465 TUint32 distance = (usec - iLastTimeout) / KOneSecondInMs; // seconds |
2451 TUint32 interval = iBackoff ? Protocol()->KeepAliveRxmt() : Protocol()->KeepAliveIntv(); |
2466 TUint32 interval = iBackoff ? Protocol()->KeepAliveRxmt() : Protocol()->KeepAliveIntv(); |
2452 |
2467 |
2453 if (distance > interval) |
2468 if (distance > interval) |
2454 { |
2469 { |
2455 // Send a keepalive probe. If no ack arrives, next one is sent after a shorter time (75 s) |
2470 // Send a keepalive probe. If no ack arrives, next one is sent after a shorter time (75 s) |
2456 LOG(Log::Printf(_L("\ttcp SAP[%u] KeepAliveTimeout(): Sending a Keep-Alive probe"), (TInt)this)); |
2471 LOG(Log::Printf(_L("\ttcp SAP[%u] KeepAliveTimeout(): Sending a Keep-Alive probe"), (TInt)this)); |
2457 SendSegment(KTcpCtlACK, iSND.UNA - 1, 0); |
2472 SendSegment(KTcpCtlACK, iSND.UNA - 1, 0); |
2458 iBackoff++; |
2473 iBackoff++; |
2459 iRetransTimer->Restart(Protocol()->KeepAliveRxmt() * KOneSecondUs); |
2474 iRetransTimer->Restart(Protocol()->KeepAliveRxmt() * KOneSecondInUs); |
2460 } |
2475 } |
2461 else |
2476 else |
2462 { |
2477 { |
2463 // This branch is entered when the first keepalive has to be issued after an idle period. |
2478 // This branch is entered when the first keepalive has to be issued after an idle period. |
2464 distance = Protocol()->KeepAliveIntv() - distance; |
2479 distance = Protocol()->KeepAliveIntv() - distance; |
2465 iRetransTimer->Restart((distance > 1800) ? |
2480 iRetransTimer->Restart((distance > 1800) ? |
2466 1800 * KOneSecondUs : (distance * KOneSecondUs)); |
2481 1800 * KOneSecondInUs : (distance * KOneSecondInUs)); |
2467 } |
2482 } |
2468 } |
2483 } |
2469 |
2484 |
2470 |
2485 |
2471 void CProviderTCP6::ResetKeepAlives() |
2486 void CProviderTCP6::ResetKeepAlives() |
2472 { |
2487 { |
2473 ASSERT(iRetransTimer); |
2488 ASSERT(iRetransTimer); |
2474 iRetransTimer->Restart((Protocol()->KeepAliveIntv() > 1800) ? |
2489 iRetransTimer->Restart((Protocol()->KeepAliveIntv() > 1800) ? |
2475 1800 * KOneSecondUs : (Protocol()->KeepAliveIntv() * KOneSecondUs)); |
2490 1800 * KOneSecondInUs : (Protocol()->KeepAliveIntv() * KOneSecondInUs)); |
2476 // Backoff is used for counting unacknowledged keepalive retransmissions during idle periods |
2491 // Backoff is used for counting unacknowledged keepalive retransmissions during idle periods |
2477 iBackoff = 0; |
2492 iBackoff = 0; |
2478 iLastTimeout = TimeStamp(); |
2493 iLastTimeout = TimeStamp(); |
2479 } |
2494 } |
2480 |
2495 |
3686 } |
3701 } |
3687 else if (!iFlags.iSackOk) |
3702 else if (!iFlags.iSackOk) |
3688 { |
3703 { |
3689 // NewReno partial ACK processing. |
3704 // NewReno partial ACK processing. |
3690 |
3705 |
3691 /* From RFC2582: |
3706 /* From RFC2582: |
3692 If this ACK does *not* acknowledge all of the data up to and |
3707 If this ACK does *not* acknowledge all of the data up to and |
3693 including "recover", then this is a partial ACK. In this case, |
3708 including "recover", then this is a partial ACK. In this case, |
3694 retransmit the first unacknowledged segment. Deflate the |
3709 retransmit the first unacknowledged segment. Deflate the |
3695 congestion window by the amount of new data acknowledged, then |
3710 congestion window by the amount of new data acknowledged, then |
3696 add back one MSS and send a new segment if permitted by the new |
3711 add back one MSS and send a new segment if permitted by the new |
3697 value of cwnd. This "partial window deflation" attempts to |
3712 value of cwnd. This "partial window deflation" attempts to |
3698 ensure that, when Fast Recovery eventually ends, approximately |
3713 ensure that, when Fast Recovery eventually ends, approximately |
3699 ssthresh amount of data will be outstanding in the network. Do |
3714 ssthresh amount of data will be outstanding in the network. Do |
3700 not exit the Fast Recovery procedure (i.e., if any duplicate ACKs |
3715 not exit the Fast Recovery procedure (i.e., if any duplicate ACKs |
3701 subsequently arrive, execute Steps 3 and 4 above). |
3716 subsequently arrive, execute Steps 3 and 4 above). |
3702 |
3717 |
3703 For the first partial ACK that arrives during Fast Recovery, also |
3718 For the first partial ACK that arrives during Fast Recovery, also |
3704 reset the retransmit timer. |
3719 reset the retransmit timer. |
3705 */ |
3720 */ |
3706 |
3721 |
3707 iCwnd -= acked; |
3722 iCwnd -= acked; |
3708 iCwnd += iSMSS; |
3723 iCwnd += iSMSS; |
3709 LOG(Log::Printf(_L("\ttcp SAP[%u] ProcessSegments(): FAST RETRANSMIT on PARTIAL ACK"), (TInt)this)); |
3724 LOG(Log::Printf(_L("\ttcp SAP[%u] ProcessSegments(): FAST RETRANSMIT on PARTIAL ACK"), (TInt)this)); |
3716 // |
3731 // |
3717 ASSERT(iSMSS); |
3732 ASSERT(iSMSS); |
3718 iDupAcks = Max(iDupAcks - acked / (TInt)iSMSS, 0); |
3733 iDupAcks = Max(iDupAcks - acked / (TInt)iSMSS, 0); |
3719 } |
3734 } |
3720 } |
3735 } |
|
3736 else if ( iDupAcks ) |
|
3737 { |
|
3738 // New data acknowledged, and not ongoing any recovery action |
|
3739 // Reset duplicate ack count |
|
3740 LOG(Log::Printf(_L("\ttcp SAP[%u] ProcessSegments(): Reset iDupAcks to 0"), (TInt)this)); |
|
3741 iDupAcks = 0; |
|
3742 } |
3721 |
3743 |
3722 // Reset limited transmit window |
3744 // Reset limited transmit window |
3723 iLwnd = 0; |
3745 iLwnd = 0; |
3724 |
3746 |
3725 // Everything acked? |
3747 // Everything acked? |
3891 if (SourceQuench() || iQuenchSeq.Outside(iSND.NXT, iSND.NXT + iSND.WND)) |
3913 if (SourceQuench() || iQuenchSeq.Outside(iSND.NXT, iSND.NXT + iSND.WND)) |
3892 { |
3914 { |
3893 iFlags.iEcnSendCWR = ETrue; |
3915 iFlags.iEcnSendCWR = ETrue; |
3894 } |
3916 } |
3895 } |
3917 } |
3896 if((iSND.NXT - ack) >0 && InState(ETcpEstablished) && (acked ==0)) |
3918 // This section used to hold the RetryACK concept, a reference can be checked |
3897 { |
3919 // from older versions(9.2/9.3). Its being removed as not required. |
3898 iRetryAck++; |
|
3899 if(iRetryAck >=4) // 4 an arbitary number; as this count does not refer to dup_ack, this will not interfere with Fast retransmission |
|
3900 { |
|
3901 LOG(Log::Printf(_L("\ttcp SAP[%u] ProcessSegments(): retransmitting the segment"), (TInt)this)); |
|
3902 SendSegments(ETrue); |
|
3903 iRetryAck = 0; // reset the retry count |
|
3904 } |
|
3905 } |
|
3906 |
3920 |
3907 } |
3921 } |
3908 } |
3922 } |
3909 |
3923 |
3910 // |
3924 // |