View | Details | Raw Unified | Return to bug 2859
Collapse All | Expand All

(-)a/src/internet/model/tcp-socket-base.cc (-11 / +13 lines)
 Lines 1583-1592   TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader) Link Here 
1583
  ReadOptions (tcpHeader, scoreboardUpdated);
1583
  ReadOptions (tcpHeader, scoreboardUpdated);
1584
1584
1585
  SequenceNumber32 ackNumber = tcpHeader.GetAckNumber ();
1585
  SequenceNumber32 ackNumber = tcpHeader.GetAckNumber ();
1586
  SequenceNumber32 oldHeadSequence = m_txBuffer->HeadSequence ();
1587
  m_txBuffer->DiscardUpTo (ackNumber);
1586
1588
1587
  // RFC 6675 Section 5: 2nd, 3rd paragraph and point (A), (B) implementation
1589
  // RFC 6675 Section 5: 2nd, 3rd paragraph and point (A), (B) implementation
1588
  // are inside the function ProcessAck
1590
  // are inside the function ProcessAck
1589
  ProcessAck (ackNumber, scoreboardUpdated);
1591
  ProcessAck (ackNumber, scoreboardUpdated, oldHeadSequence);
1590
1592
1591
  // If there is any data piggybacked, store it into m_rxBuffer
1593
  // If there is any data piggybacked, store it into m_rxBuffer
1592
  if (packet->GetSize () > 0)
1594
  if (packet->GetSize () > 0)
 Lines 1600-1606   TcpSocketBase::ReceivedAck (Ptr<Packet> packet, const TcpHeader& tcpHeader) Link Here 
1600
}
1602
}
1601
1603
1602
void
1604
void
1603
TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpdated)
1605
TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpdated,
1606
                           const SequenceNumber32 &oldHeadSequence)
1604
{
1607
{
1605
  NS_LOG_FUNCTION (this << ackNumber << scoreboardUpdated);
1608
  NS_LOG_FUNCTION (this << ackNumber << scoreboardUpdated);
1606
  // RFC 6675, Section 5, 2nd paragraph:
1609
  // RFC 6675, Section 5, 2nd paragraph:
 Lines 1629-1635   TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpd Link Here 
1629
1632
1630
  bool isDupack = m_sackEnabled ?
1633
  bool isDupack = m_sackEnabled ?
1631
        scoreboardUpdated
1634
        scoreboardUpdated
1632
      : ackNumber == m_txBuffer->HeadSequence () &&
1635
      : ackNumber == oldHeadSequence &&
1633
        ackNumber < m_tcb->m_highTxMark;
1636
        ackNumber < m_tcb->m_highTxMark;
1634
1637
1635
  // RFC 6675, Section 5, 3rd paragraph:
1638
  // RFC 6675, Section 5, 3rd paragraph:
 Lines 1639-1645   TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpd Link Here 
1639
  if (isDupack)
1642
  if (isDupack)
1640
    {
1643
    {
1641
      NS_LOG_DEBUG ("ACK of " << ackNumber <<
1644
      NS_LOG_DEBUG ("ACK of " << ackNumber <<
1642
                    " SND.UNA=" << m_txBuffer->HeadSequence () <<
1645
                    " SND.UNA=" << oldHeadSequence <<
1643
                    " SND.NXT=" << m_tcb->m_nextTxSequence <<
1646
                    " SND.NXT=" << m_tcb->m_nextTxSequence <<
1644
                    " in state: " << TcpSocketState::TcpCongStateName[m_tcb->m_congState] <<
1647
                    " in state: " << TcpSocketState::TcpCongStateName[m_tcb->m_congState] <<
1645
                    " with m_recover: " << m_recover);
1648
                    " with m_recover: " << m_recover);
 Lines 1648-1660   TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpd Link Here 
1648
      DupAck ();
1651
      DupAck ();
1649
    }
1652
    }
1650
1653
1651
  if (ackNumber == m_txBuffer->HeadSequence ()
1654
  if (ackNumber == oldHeadSequence
1652
      && ackNumber == m_tcb->m_highTxMark)
1655
      && ackNumber == m_tcb->m_highTxMark)
1653
    {
1656
    {
1654
      // Dupack, but the ACK is precisely equal to the nextTxSequence
1657
      // Dupack, but the ACK is precisely equal to the nextTxSequence
1655
      return;
1658
      return;
1656
    }
1659
    }
1657
  else if (ackNumber == m_txBuffer->HeadSequence ()
1660
  else if (ackNumber == oldHeadSequence
1658
           && ackNumber > m_tcb->m_highTxMark)
1661
           && ackNumber > m_tcb->m_highTxMark)
1659
    {
1662
    {
1660
      // ACK of the FIN bit ... nextTxSequence is not updated since we
1663
      // ACK of the FIN bit ... nextTxSequence is not updated since we
 Lines 1662-1677   TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpd Link Here 
1662
      NS_LOG_DEBUG ("Update nextTxSequence manually to " << ackNumber);
1665
      NS_LOG_DEBUG ("Update nextTxSequence manually to " << ackNumber);
1663
      m_tcb->m_nextTxSequence = ackNumber;
1666
      m_tcb->m_nextTxSequence = ackNumber;
1664
    }
1667
    }
1665
  else if (ackNumber == m_txBuffer->HeadSequence ())
1668
  else if (ackNumber == oldHeadSequence)
1666
    {
1669
    {
1667
      // DupAck. Artificially call PktsAcked: after all, one segment has been ACKed.
1670
      // DupAck. Artificially call PktsAcked: after all, one segment has been ACKed.
1668
      m_congestionControl->PktsAcked (m_tcb, 1, m_lastRtt);
1671
      m_congestionControl->PktsAcked (m_tcb, 1, m_lastRtt);
1669
    }
1672
    }
1670
  else if (ackNumber > m_txBuffer->HeadSequence ())
1673
  else if (ackNumber > oldHeadSequence)
1671
    {
1674
    {
1672
      // Please remember that, with SACK, we can enter here even if we
1675
      // Please remember that, with SACK, we can enter here even if we
1673
      // received a dupack.
1676
      // received a dupack.
1674
      uint32_t bytesAcked = ackNumber - m_txBuffer->HeadSequence ();
1677
      uint32_t bytesAcked = ackNumber - oldHeadSequence;
1675
      uint32_t segsAcked  = bytesAcked / m_tcb->m_segmentSize;
1678
      uint32_t segsAcked  = bytesAcked / m_tcb->m_segmentSize;
1676
      m_bytesAckedNotProcessed += bytesAcked % m_tcb->m_segmentSize;
1679
      m_bytesAckedNotProcessed += bytesAcked % m_tcb->m_segmentSize;
1677
1680
 Lines 1702-1708   TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpd Link Here 
1702
      // the CA_RECOVERY phase. Just process this partial ack (RFC 5681)
1705
      // the CA_RECOVERY phase. Just process this partial ack (RFC 5681)
1703
      if (ackNumber < m_recover && m_tcb->m_congState == TcpSocketState::CA_RECOVERY)
1706
      if (ackNumber < m_recover && m_tcb->m_congState == TcpSocketState::CA_RECOVERY)
1704
        {
1707
        {
1705
          m_txBuffer->DiscardUpTo (ackNumber);
1706
          if (!m_sackEnabled)
1708
          if (!m_sackEnabled)
1707
            {
1709
            {
1708
              // Manually set the head as lost, it will be retransmitted.
1710
              // Manually set the head as lost, it will be retransmitted.
 Lines 3111-3117   TcpSocketBase::NewAck (SequenceNumber32 const& ack, bool resetRTO) Link Here 
3111
  // Note the highest ACK and tell app to send more
3113
  // Note the highest ACK and tell app to send more
3112
  NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack <<
3114
  NS_LOG_LOGIC ("TCP " << this << " NewAck " << ack <<
3113
                " numberAck " << (ack - m_txBuffer->HeadSequence ())); // Number bytes ack'ed
3115
                " numberAck " << (ack - m_txBuffer->HeadSequence ())); // Number bytes ack'ed
3114
  m_txBuffer->DiscardUpTo (ack);
3116
3115
  if (GetTxAvailable () > 0)
3117
  if (GetTxAvailable () > 0)
3116
    {
3118
    {
3117
      NotifySend (GetTxAvailable ());
3119
      NotifySend (GetTxAvailable ());
(-)a/src/internet/model/tcp-socket-base.h (-1 / +3 lines)
 Lines 892-900   protected: Link Here 
892
   * \brief Process a received ack
892
   * \brief Process a received ack
893
   * \param ackNumber ack number
893
   * \param ackNumber ack number
894
   * \param scoreboardUpdated if true indicates that the scoreboard has been
894
   * \param scoreboardUpdated if true indicates that the scoreboard has been
895
   * \param oldHeadSequence value of HeadSequence before ack
895
   * updated with SACK information
896
   * updated with SACK information
896
   */
897
   */
897
  virtual void ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpdated);
898
  virtual void ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpdated,
899
                           const SequenceNumber32 &oldHeadSequence);
898
900
899
  /**
901
  /**
900
   * \brief Recv of a data, put into buffer, call L7 to get it if necessary
902
   * \brief Recv of a data, put into buffer, call L7 to get it if necessary
(-)a/src/internet/test/tcp-bytes-in-flight-test.cc (+4 lines)
 Lines 199-204   TcpBytesInFlightTest::Rx (const Ptr<const Packet> p, const TcpHeader &h, SocketW Link Here 
199
                {
199
                {
200
                  // Partial ACK: Update the dupAck received count
200
                  // Partial ACK: Update the dupAck received count
201
                  m_dupAckRecv -= diff / GetSegSize (SENDER);
201
                  m_dupAckRecv -= diff / GetSegSize (SENDER);
202
                  // During fast recovery the TCP data sender respond to a partial acknowledgment
203
                  // by inferring that the next in-sequence packet has been lost (RFC5681)
204
                  m_guessedBytesInFlight -= GetSegSize (SENDER);
202
                }
205
                }
203
            }
206
            }
204
207
 Lines 224-229   TcpBytesInFlightTest::Rx (const Ptr<const Packet> p, const TcpHeader &h, SocketW Link Here 
224
          if (m_dupAckRecv == 3)
227
          if (m_dupAckRecv == 3)
225
            {
228
            {
226
              NS_LOG_DEBUG ("Loss of a segment detected");
229
              NS_LOG_DEBUG ("Loss of a segment detected");
230
              m_guessedBytesInFlight -= GetSegSize (SENDER);
227
            }
231
            }
228
          NS_LOG_DEBUG ("Dupack received, Update m_guessedBytesInFlight to " <<
232
          NS_LOG_DEBUG ("Dupack received, Update m_guessedBytesInFlight to " <<
229
                        m_guessedBytesInFlight);
233
                        m_guessedBytesInFlight);

Return to bug 2859