Fri Feb 19 15:52:21 2016 +0100 8def793 internet: (fixes #1783) BytesInFlight conforms to RFC 4898  [Natale Patriciello] diff --git a/src/internet/model/tcp-socket-base.cc b/src/internet/model/tcp-socket-base.cc index 77e0efe..a96f42f 100644 --- a/src/internet/model/tcp-socket-base.cc +++ b/src/internet/model/tcp-socket-base.cc @@ -299,6 +299,7 @@ TcpSocketBase::TcpSocketBase (void) m_recover (0), // Set to the initial sequence number m_retxThresh (3), m_limitedTx (false), + m_retransOut (0), m_congestionControl (0), m_isFirstPartialAck (true) { @@ -368,6 +369,7 @@ TcpSocketBase::TcpSocketBase (const TcpSocketBase& sock) m_recover (sock.m_recover), m_retxThresh (sock.m_retxThresh), m_limitedTx (sock.m_limitedTx), + m_retransOut (sock.m_retransOut), m_isFirstPartialAck (sock.m_isFirstPartialAck), m_txTrace (sock.m_txTrace), m_rxTrace (sock.m_rxTrace) @@ -1511,6 +1513,7 @@ TcpSocketBase::ReceivedAck (Ptr packet, const TcpHeader& tcpHeader) m_tcb->m_congState = TcpSocketState::CA_OPEN; m_congestionControl->PktsAcked (m_tcb, segsAcked, m_lastRtt); m_dupAckCount = 0; + m_retransOut = 0; NS_LOG_DEBUG ("DISORDER -> OPEN"); } @@ -1544,6 +1547,7 @@ TcpSocketBase::ReceivedAck (Ptr packet, const TcpHeader& tcpHeader) callCongestionControl = false; // No congestion control on cWnd show be invoked m_dupAckCount -= segsAcked; // Update the dupAckCount + m_retransOut--; // at least one retransmission has reached the other side m_txBuffer->DiscardUpTo (ackNumber); //Bug 1850: retransmit before newack DoRetransmit (); // Assume the next seq is lost. Retransmit lost packet @@ -1573,6 +1577,7 @@ TcpSocketBase::ReceivedAck (Ptr packet, const TcpHeader& tcpHeader) BytesInFlight () + m_tcb->m_segmentSize); m_isFirstPartialAck = true; m_dupAckCount = 0; + m_retransOut = 0; /* This FULL ACK acknowledge the fact that one segment has been * previously lost and now successfully received. All others have @@ -1594,6 +1599,7 @@ TcpSocketBase::ReceivedAck (Ptr packet, const TcpHeader& tcpHeader) m_isFirstPartialAck = true; m_congestionControl->PktsAcked (m_tcb, segsAcked, m_lastRtt); m_dupAckCount = 0; + m_retransOut = 0; m_tcb->m_congState = TcpSocketState::CA_OPEN; NS_LOG_DEBUG ("LOSS -> OPEN"); } @@ -2555,7 +2561,26 @@ uint32_t TcpSocketBase::BytesInFlight () { NS_LOG_FUNCTION (this); - uint32_t bytesInFlight = m_highTxMark.Get () - m_txBuffer->HeadSequence (); + // Previous (see bug 1783): + // uint32_t bytesInFlight = m_highTxMark.Get () - m_txBuffer->HeadSequence (); + // RFC 4898 page 23 + // PipeSize=SND.NXT-SND.UNA+(retransmits-dupacks)*CurMSS + + // flightSize == UnAckDataCount (), but we avoid the call to save log lines + uint32_t flightSize = m_nextTxSequence.Get () - m_txBuffer->HeadSequence (); + uint32_t duplicatedSize; + uint32_t bytesInFlight; + + if (m_retransOut > m_dupAckCount) + { + duplicatedSize = (m_retransOut - m_dupAckCount)*m_tcb->m_segmentSize; + bytesInFlight = flightSize + duplicatedSize; + } + else + { + duplicatedSize = (m_dupAckCount - m_retransOut)*m_tcb->m_segmentSize; + bytesInFlight = duplicatedSize > flightSize ? 0 : flightSize - duplicatedSize; + } // m_bytesInFlight is traced; avoid useless assignments which would fire // fruitlessly the callback @@ -2889,9 +2914,6 @@ TcpSocketBase::Retransmit () * are not able to retransmit anything because of local congestion. */ - m_nextTxSequence = m_txBuffer->HeadSequence (); // Restart from highest Ack - m_dupAckCount = 0; - if (m_tcb->m_congState != TcpSocketState::CA_LOSS) { m_tcb->m_congState = TcpSocketState::CA_LOSS; @@ -2899,6 +2921,9 @@ TcpSocketBase::Retransmit () m_tcb->m_cWnd = m_tcb->m_segmentSize; } + m_nextTxSequence = m_txBuffer->HeadSequence (); // Restart from highest Ack + m_dupAckCount = 0; + NS_LOG_DEBUG ("RTO. Reset cwnd to " << m_tcb->m_cWnd << ", ssthresh to " << m_tcb->m_ssThresh << ", restart from seqnum " << m_nextTxSequence); DoRetransmit (); // Retransmit the packet @@ -2946,6 +2971,8 @@ TcpSocketBase::DoRetransmit () // Retransmit a data packet: Call SendDataPacket uint32_t sz = SendDataPacket (m_txBuffer->HeadSequence (), m_tcb->m_segmentSize, true); + ++m_retransOut; + // In case of RTO, advance m_nextTxSequence m_nextTxSequence = std::max (m_nextTxSequence.Get (), m_txBuffer->HeadSequence () + sz); diff --git a/src/internet/model/tcp-socket-base.h b/src/internet/model/tcp-socket-base.h index aef3fd9..e037121 100644 --- a/src/internet/model/tcp-socket-base.h +++ b/src/internet/model/tcp-socket-base.h @@ -956,6 +956,7 @@ protected: SequenceNumber32 m_recover; //!< Previous highest Tx seqnum for fast recovery uint32_t m_retxThresh; //!< Fast Retransmit threshold bool m_limitedTx; //!< perform limited transmit + uint32_t m_retransOut; //!< Number of retransmission in this window // Transmission Control Block Ptr m_tcb; //!< Congestion control informations