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).
This commit is contained in:
Natale Patriciello
2015-10-16 10:38:35 -07:00
parent 3fd6f45051
commit c86045ee2d

View File

@@ -1126,7 +1126,31 @@ TcpSocketBase::ProcessEstablished (Ptr<Packet> 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> 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)
{