--- i/src/internet/model/tcp-socket-base.cc +++ i/src/internet/model/tcp-socket-base.cc @@ -1700,7 +1700,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, scoreboardUpdated, oldHeadSequence, packet->GetSize ()); // If there is any data piggybacked, store it into m_rxBuffer if (packet->GetSize () > 0) @@ -1715,7 +1715,7 @@ TcpSocketBase::ReceivedAck (Ptr packet, const TcpHeader& tcpHeader) void TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpdated, - const SequenceNumber32 &oldHeadSequence) + const SequenceNumber32 &oldHeadSequence, uint32_t size) { NS_LOG_FUNCTION (this << ackNumber << scoreboardUpdated); // RFC 6675, Section 5, 2nd paragraph: @@ -1742,10 +1742,16 @@ TcpSocketBase::ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpd * HighData (m_highTxMark) */ - bool isDupack = m_sackEnabled ? - scoreboardUpdated - : ackNumber == oldHeadSequence && - ackNumber < m_tcb->m_highTxMark; + bool isDupack = scoreboardUpdated; + + if (!m_sackEnabled) + { + // SYN and FIN are both OFF thanks to the state processing + isDupack = UnAckDataCount () > 0 && // condition (a) + size == 0 && // condition (b) + ackNumber == oldHeadSequence && // condition (d) + ackNumber < m_tcb->m_highTxMark; // safety consideration + } NS_LOG_DEBUG ("ACK of " << ackNumber << " SND.UNA=" << oldHeadSequence << --- i/src/internet/model/tcp-socket-base.h +++ i/src/internet/model/tcp-socket-base.h @@ -962,10 +962,11 @@ protected: * \param ackNumber ack number * \param scoreboardUpdated if true indicates that the scoreboard has been * \param oldHeadSequence value of HeadSequence before ack + * \param size Packet size * updated with SACK information */ virtual void ProcessAck (const SequenceNumber32 &ackNumber, bool scoreboardUpdated, - const SequenceNumber32 &oldHeadSequence); + const SequenceNumber32 &oldHeadSequence, uint32_t size); /** * \brief Recv of a data, put into buffer, call L7 to get it if necessary