From c86045ee2d32dadf3440102a14a825eb8fb89ccc Mon Sep 17 00:00:00 2001 From: Natale Patriciello Date: Fri, 16 Oct 2015 10:38:35 -0700 Subject: [PATCH] Management of ignored ACK moved away from ReceivedAck The function ReceivedAck contained some if/else switches to manage ACK which, by definition, should have been ignored, like old ACKs (SEG.ACK < SND.UNA). The code still misses the management of the mitigation of Blind Data Injection Attack. This patch moves these switches inside ProcessEstablished, to simplify the ReceivedAck function, which now manages only valid ACKS. To complete the overview, one more condition has been added, which is the case of an out-of-order ACK (SEG.ACK > SND.NXT). --- src/internet/model/tcp-socket-base.cc | 38 ++++++++++++++++++++------- 1 file changed, 28 insertions(+), 10 deletions(-) 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) {