diff --git a/src/internet/model/tcp-socket-base.cc b/src/internet/model/tcp-socket-base.cc index b72dfc32c..76e0bf726 100644 --- a/src/internet/model/tcp-socket-base.cc +++ b/src/internet/model/tcp-socket-base.cc @@ -1126,7 +1126,31 @@ TcpSocketBase::ProcessEstablished (Ptr packet, const TcpHeader& tcpHeade // Different flags are different events if (tcpflags == TcpHeader::ACK) { - ReceivedAck (packet, tcpHeader); + if (tcpHeader.GetAckNumber () < m_txBuffer->HeadSequence ()) + { + // Case 1: If the ACK is a duplicate (SEG.ACK < SND.UNA), it can be ignored. + // Pag. 72 RFC 793 + NS_LOG_LOGIC ("Ignored ack of " << tcpHeader.GetAckNumber () << + " SND.UNA = " << m_txBuffer->HeadSequence ()); + + // TODO: RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation] + } + else if (tcpHeader.GetAckNumber() > m_highTxMark) + { + // If the ACK acks something not yet sent (SEG.ACK > HighTxMark) then + // send an ACK, drop the segment, and return. + // Pag. 72 RFC 793 + NS_LOG_LOGIC ("Ignored ack of " << tcpHeader.GetAckNumber () << + " HighTxMark = " << m_highTxMark); + + SendEmptyPacket (TcpHeader::ACK); + } + else + { + // SND.UNA < SEG.ACK =< HighTxMark + // Pag. 72 RFC 793 + ReceivedAck (packet, tcpHeader); + } } else if (tcpflags == TcpHeader::SYN) { // Received SYN, old NS-3 behaviour is to set state to SYN_RCVD and @@ -1165,15 +1189,9 @@ TcpSocketBase::ReceivedAck (Ptr packet, const TcpHeader& tcpHeader) { NS_LOG_FUNCTION (this << tcpHeader); - // Received ACK. Compare the ACK number against highest unacked seqno - if (0 == (tcpHeader.GetFlags () & TcpHeader::ACK)) - { // Ignore if no ACK flag - } - else if (tcpHeader.GetAckNumber () < m_txBuffer->HeadSequence ()) - { // Case 1: Old ACK, ignored. - NS_LOG_LOGIC ("Ignored ack of " << tcpHeader.GetAckNumber ()); - } - else if (tcpHeader.GetAckNumber () == m_txBuffer->HeadSequence ()) + NS_ASSERT (0 != (tcpHeader.GetFlags () & TcpHeader::ACK)); + + if (tcpHeader.GetAckNumber () == m_txBuffer->HeadSequence ()) { // Case 2: Potentially a duplicated ACK if (tcpHeader.GetAckNumber () < m_nextTxSequence && packet->GetSize() == 0) {