diff --git a/src/internet/model/tcp-socket-base.cc b/src/internet/model/tcp-socket-base.cc index 39abdf92a..760101a61 100644 --- a/src/internet/model/tcp-socket-base.cc +++ b/src/internet/model/tcp-socket-base.cc @@ -1506,7 +1506,7 @@ TcpSocketBase::IsTcpOptionEnabled (uint8_t kind) const } void -TcpSocketBase::ReadOptions (const TcpHeader &tcpHeader, bool &scoreboardUpdated) +TcpSocketBase::ReadOptions (const TcpHeader &tcpHeader, uint32_t *bytesSacked) { NS_LOG_FUNCTION (this << tcpHeader); TcpHeader::TcpOptionList::const_iterator it; @@ -1520,7 +1520,7 @@ TcpSocketBase::ReadOptions (const TcpHeader &tcpHeader, bool &scoreboardUpdated) switch (option->GetKind ()) { case TcpOption::SACK: - scoreboardUpdated = ProcessOptionSack (option); + *bytesSacked = ProcessOptionSack (option); break; default: continue; @@ -1680,8 +1680,8 @@ TcpSocketBase::ReceivedAck (Ptr packet, const TcpHeader& tcpHeader) // RFC 6675, Section 5, 1st paragraph: // Upon the receipt of any ACK containing SACK information, the // scoreboard MUST be updated via the Update () routine (done in ReadOptions) - bool scoreboardUpdated = false; - ReadOptions (tcpHeader, scoreboardUpdated); + uint32_t bytesSacked = 0; + ReadOptions (tcpHeader, &bytesSacked); SequenceNumber32 ackNumber = tcpHeader.GetAckNumber (); SequenceNumber32 oldHeadSequence = m_txBuffer->HeadSequence (); @@ -1704,7 +1704,7 @@ TcpSocketBase::ReceivedAck (Ptr packet, const TcpHeader& tcpHeader) // RFC 6675 Section 5: 2nd, 3rd paragraph and point (A), (B) implementation // are inside the function ProcessAck - ProcessAck (ackNumber, scoreboardUpdated, oldHeadSequence); + ProcessAck (ackNumber, (bytesSacked > 0), oldHeadSequence); // If there is any data piggybacked, store it into m_rxBuffer if (packet->GetSize () > 0) @@ -3946,14 +3946,13 @@ TcpSocketBase::AddOptionWScale (TcpHeader &header) static_cast (m_rcvWindShift)); } -bool +uint32_t TcpSocketBase::ProcessOptionSack (const Ptr option) { NS_LOG_FUNCTION (this << option); Ptr s = DynamicCast (option); - TcpOptionSack::SackList list = s->GetSackList (); - return m_txBuffer->Update (list); + return m_txBuffer->Update (s->GetSackList ()); } void diff --git a/src/internet/model/tcp-socket-base.h b/src/internet/model/tcp-socket-base.h index 1412e6068..2ac94698c 100644 --- a/src/internet/model/tcp-socket-base.h +++ b/src/internet/model/tcp-socket-base.h @@ -1051,10 +1051,9 @@ protected: * Timestamp and Window scale are managed in other pieces of code. * * \param tcpHeader Header of the segment - * \param scoreboardUpdated indicates if the scoreboard was updated due to a - * SACK option + * \param [out] bytesSacked Number of bytes SACKed, or 0 */ - void ReadOptions (const TcpHeader &tcpHeader, bool &scoreboardUpdated); + void ReadOptions (const TcpHeader &tcpHeader, uint32_t *bytesSacked); /** * \brief Return true if the specified option is enabled @@ -1106,9 +1105,9 @@ protected: * \brief Read the SACK option * * \param option SACK option from the header - * \returns true in case of an update to the SACKed blocks + * \returns the number of bytes sacked by this option */ - bool ProcessOptionSack (const Ptr option); + uint32_t ProcessOptionSack(const Ptr option); /** * \brief Add the SACK PERMITTED option to the header diff --git a/src/internet/model/tcp-tx-buffer.cc b/src/internet/model/tcp-tx-buffer.cc index 735f298bb..8ea00a543 100644 --- a/src/internet/model/tcp-tx-buffer.cc +++ b/src/internet/model/tcp-tx-buffer.cc @@ -746,23 +746,23 @@ TcpTxBuffer::DiscardUpTo (const SequenceNumber32& seq) ConsistencyCheck (); } -bool +uint32_t TcpTxBuffer::Update (const TcpOptionSack::SackList &list) { NS_LOG_FUNCTION (this); NS_LOG_INFO ("Updating scoreboard, got " << list.size () << " blocks to analyze"); - bool modified = false; + uint32_t bytesSacked = 0; for (auto option_it = list.begin (); option_it != list.end (); ++option_it) { PacketList::iterator item_it = m_sentList.begin (); SequenceNumber32 beginOfCurrentPacket = m_firstByteSeq; - if (m_firstByteSeq + m_sentSize < (*option_it).first && !modified) + if (m_firstByteSeq + m_sentSize < (*option_it).first) { NS_LOG_INFO ("Not updating scoreboard, the option block is outside the sent list"); - return false; + return bytesSacked; } while (item_it != m_sentList.end ()) @@ -794,6 +794,7 @@ TcpTxBuffer::Update (const TcpOptionSack::SackList &list) (*item_it)->m_sacked = true; m_sackedOut += (*item_it)->m_packet->GetSize (); + bytesSacked += (*item_it)->m_packet->GetSize (); if (m_highestSack.first == m_sentList.end() || m_highestSack.second <= beginOfCurrentPacket + pktSize) @@ -806,7 +807,6 @@ TcpTxBuffer::Update (const TcpOptionSack::SackList &list) ", found in the sackboard, sacking, current highSack: " << m_highestSack.second); } - modified = true; } else if (beginOfCurrentPacket + pktSize > (*option_it).second) { @@ -822,9 +822,9 @@ TcpTxBuffer::Update (const TcpOptionSack::SackList &list) } } - if (modified) + if (bytesSacked > 0) { - NS_ASSERT_MSG (modified && m_highestSack.first != m_sentList.end(), "Buffer status: " << *this); + NS_ASSERT_MSG (m_highestSack.first != m_sentList.end(), "Buffer status: " << *this); UpdateLostCount (); } @@ -833,7 +833,7 @@ TcpTxBuffer::Update (const TcpOptionSack::SackList &list) //NS_ASSERT (list.size () == 0 || modified); // Assert for duplicated SACK or // impossiblity to map the option into the sent blocks ConsistencyCheck (); - return modified; + return bytesSacked; } void diff --git a/src/internet/model/tcp-tx-buffer.h b/src/internet/model/tcp-tx-buffer.h index c4cc87fa7..fd9e96e7e 100644 --- a/src/internet/model/tcp-tx-buffer.h +++ b/src/internet/model/tcp-tx-buffer.h @@ -267,9 +267,9 @@ public: /** * \brief Update the scoreboard * \param list list of SACKed blocks - * \returns true in case of an update + * \returns the number of bytes newly sacked by the list of blocks */ - bool Update (const TcpOptionSack::SackList &list); + uint32_t Update (const TcpOptionSack::SackList &list); /** * \brief Check if a segment is lost