Only first partial ACK should reset the RTO
authorNatale Patriciello <natale.patriciello@gmail.com>
Fri, 16 Oct 2015 10:42:36 -0700
changeset 11708 965c3ab092a2
parent 11707 b9699e5e3ad3
child 11709 98cbaaa6a968
Only first partial ACK should reset the RTO
src/internet/model/tcp-socket-base.cc
src/internet/model/tcp-socket-base.h
--- a/src/internet/model/tcp-socket-base.cc	Fri Oct 16 10:42:30 2015 -0700
+++ b/src/internet/model/tcp-socket-base.cc	Fri Oct 16 10:42:36 2015 -0700
@@ -1374,6 +1374,7 @@
   else if (tcpHeader.GetAckNumber () > m_txBuffer->HeadSequence ())
     { // Case 3: New ACK, reset m_dupAckCount and update m_txBuffer
       bool callCongestionControl = true;
+      bool resetRTO = true;
 
       /* The following switch is made because m_dupAckCount can be
        * "inflated" through out-of-order segments (e.g. from retransmission,
@@ -1443,6 +1444,10 @@
                 {
                   m_isFirstPartialAck = false;
                 }
+              else
+                {
+                  resetRTO = false;
+                }
 
               /* This partial ACK acknowledge the fact that one segment has been
                * previously lost and now successfully received. All others have
@@ -1495,7 +1500,12 @@
                         " ssTh: " << m_tcb->m_ssThresh);
         }
 
-      NewAck (tcpHeader.GetAckNumber ());
+      if (m_isFirstPartialAck == false)
+        {
+          NS_ASSERT (m_tcb->m_ackState == TcpSocketState::RECOVERY);
+        }
+
+      NewAck (tcpHeader.GetAckNumber (), resetRTO);
 
       // Try to send more data
       if (!m_sendPendingDataEvent.IsRunning ())
@@ -2572,11 +2582,11 @@
 // when the three-way handshake completed. This cancels retransmission timer
 // and advances Tx window
 void
-TcpSocketBase::NewAck (SequenceNumber32 const& ack)
+TcpSocketBase::NewAck (SequenceNumber32 const& ack, bool resetRTO)
 {
   NS_LOG_FUNCTION (this << ack);
 
-  if (m_state != SYN_RCVD)
+  if (m_state != SYN_RCVD && resetRTO)
     { // Set RTO unless the ACK is received in SYN_RCVD state
       NS_LOG_LOGIC (this << " Cancelled ReTxTimeout event which was set to expire at " <<
                     (Simulator::Now () + Simulator::GetDelayLeft (m_retxEvent)).GetSeconds ());
--- a/src/internet/model/tcp-socket-base.h	Fri Oct 16 10:42:30 2015 -0700
+++ b/src/internet/model/tcp-socket-base.h	Fri Oct 16 10:42:36 2015 -0700
@@ -755,8 +755,9 @@
   /**
    * \brief Update buffers w.r.t. ACK
    * \param seq the sequence number
+   * \param resetRTO indicates if RTO should be reset
    */
-  virtual void NewAck (SequenceNumber32 const& seq);
+  virtual void NewAck (SequenceNumber32 const& seq, bool resetRTO);
 
   /**
    * \brief Call Retransmit() upon RTO event