How faithfully does NS-3's TCP RFC 5681, TCP congestion control?

389 views
Skip to first unread message

Gautam Thaker

unread,
Feb 6, 2010, 12:10:51 PM2/6/10
to ns-3-...@googlegroups.com
Hi.

http://tools.ietf.org/html/rfc5681

"This document defines TCP's four intertwined congestion control
algorithms: slow start, congestion avoidance, fast retransmit, and
fast recovery. In addition, the document specifies how TCP should
begin transmission after a relatively long idle period, as well as
discussing various acknowledgment generation methods."

I was wondering how well does NS-3's TCP/IP "stack" support details in this RFC?

Gautam

Tom Henderson

unread,
Feb 8, 2010, 1:46:49 AM2/8/10
to ns-3-...@googlegroups.com

There are two implementations for ns-3, the native ns-3 TCP
implementation (provided by "ns3::TcpSocketFactory") and the Network
Simulation Cradle (provided by "ns3::NscTcpSocketFactory").

Regarding RFC 5681 compliance, the native TCP supports Tahoe (slow start
and congestion avoidance; section 3.1) but does not support PMTUD or
ABC, as far as I know. Since it is Tahoe, it doesn't support Fast
Retransmit/Recovery, or the options listed in Section 4.

The NSC TCP supports Linux TCP behavior as of recent kernels (e.g.
2.6.26 is typically used). I think that much of RFC 5681 should be
supported, but Linux has done its own thing in a few areas (e.g. see:
http://kb.pert.geant.net/PERTKB/TCPAcks).

Tom

Juan Pablo Poujade

unread,
Feb 8, 2010, 8:07:08 AM2/8/10
to ns-3-...@googlegroups.com

Actually, the native TCP implementation in NS-3 (supposed to be Tahoe) supports the Fast Retransmit feature, but It does not support Fast Recovery. You can see how Fast Retransmit is implemented in the method called DupAck from the class TcpSocketImpl:

void TcpSocketImpl::DupAck (const TcpHeader& t, uint32_t count)
{
  NS_LOG_FUNCTION (this << "t " << count);
  NS_LOG_LOGIC ("TcpSocketImpl " << this << " DupAck " <<  t.GetAckNumber ()
      << ", count " << count
      << ", time " << Simulator::Now ());
  if (count == 3)
  { // Count of three indicates triple duplicate ack
    m_ssThresh = Window () / 2; // Per RFC2581
    m_ssThresh = std::max (m_ssThresh, 2 * m_segmentSize);
    NS_LOG_LOGIC("TcpSocketImpl " << this << "Tahoe TDA, time " << Simulator::Now ()
        << " seq " << t.GetAckNumber ()
        << " in flight " << BytesInFlight ()
        << " new ssthresh " << m_ssThresh);

    m_cWnd = m_segmentSize; // Collapse cwnd (re-enter slowstart)
    // For Tahoe, we also reset nextTxSeq
    m_nextTxSequence = m_highestRxAck;
    SendPendingData (m_connected);
  }
}

In the code you can see that whe it receives 3 consecutive DupAcks (count == 3), it reduces the congestion window and then retransmit the "lost" segment using the following sentences:

m_nextTxSequence = m_highestRxAck;
SendPendingData (m_connected);

The bad thing is that it restarts from the scratch, retransmiting every segment sent after m_highestRxAck. That is beacuse this implementation doesn´t have the Fast Recovery feature.

Is my interpretation wrong ??

Regards

Juan Pablo Poujade
 

2010/2/8 Tom Henderson <to...@tomh.org>


--
You received this message because you are subscribed to the Google Groups "ns-3-users" group.
To post to this group, send email to ns-3-...@googlegroups.com.
To unsubscribe from this group, send email to ns-3-users+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/ns-3-users?hl=en.


Tom Henderson

unread,
Feb 8, 2010, 10:41:57 AM2/8/10
to ns-3-...@googlegroups.com
On 2/8/10 5:07 AM, Juan Pablo Poujade wrote:
>
> Actually, the native TCP implementation in NS-3 (supposed to be Tahoe)
> supports the Fast Retransmit feature, but It does not support Fast
> Recovery. You can see how Fast Retransmit is implemented in the method
> called DupAck from the class TcpSocketImpl:

I agree, it is probably best described as Tahoe plus Fast Retransmit.

Tom

Antti Mäkelä

unread,
Feb 24, 2010, 7:18:01 AM2/24/10
to ns-3-users
On Feb 8, 5:41 pm, Tom Henderson <t...@tomh.org> wrote:
> > Actually, the native TCP implementation in NS-3 (supposed to be Tahoe)
> > supports theFastRetransmit feature, but It does not supportFast
> >Recovery. You can see howFastRetransmit is implemented in the method

> > called DupAck from the class TcpSocketImpl:
> I agree, it is probably best described as Tahoe plusFastRetransmit.

I wonder how much work would be needed to include also fast recovery -
what do you guys think?

I'm not sure I can just submit a patch based on this since I'm already
running with a heavily modified tcp-socket-impl.cc that has added
tracevalues for sequence numbers and retransmits..anyway, it seems
relatively few changes. Comments?

Quoth the RFC (and I really hope google groups don't screw up
formatting)

The fast retransmit and fast recovery algorithms are implemented
together as follows.

1. On the first and second duplicate ACKs received at a sender, a
TCP SHOULD send a segment of previously unsent data per
[RFC3042]
provided that the receiver's advertised window allows, the
total
FlightSize would remain less than or equal to cwnd plus 2*SMSS,
and that new data is available for transmission. Further, the
TCP sender MUST NOT change cwnd to reflect these two segments
[RFC3042]. Note that a sender using SACK [RFC2018] MUST NOT
send
new data unless the incoming duplicate acknowledgment contains
new SACK information.

2. When the third duplicate ACK is received, a TCP MUST set
ssthresh
to no more than the value given in equation (4). When
[RFC3042]
is in use, additional data sent in limited transmit MUST NOT be
included in this calculation.

This is already in - the fast retransmit part. The equation 4 is

ssthresh = max (FlightSize / 2, 2*SMSS)
and it's already in source code as


m_ssThresh = Window () / 2; // Per RFC2581
m_ssThresh = std::max (m_ssThresh, 2 * m_segmentSize);

(I think)

However, at this point we don't follow through on things:

3. The lost segment starting at SND.UNA MUST be retransmitted and
cwnd set to ssthresh plus 3*SMSS. This artificially "inflates"
the congestion window by the number of segments (three) that
have
left the network and which the receiver has buffered.

instead, we have

m_cWnd = m_segmentSize; // Collapse cwnd (re-enter slowstart)

So, instead, replace this with
m_cWnd = m_ssThresh + (3*m_segmentSize).

Then

4. For each additional duplicate ACK received (after the third),
cwnd MUST be incremented by SMSS. This artificially inflates
the
congestion window in order to reflect the additional segment
that
has left the network.

So, this should be simple enough:

if (count > 3) { m_cWnd += m_segmentSize; }

5. When previously unsent data is available and the new value of
cwnd and the receiver's advertised window allow, a TCP SHOULD
send 1*SMSS bytes of previously unsent data.

I'm not sure whether this needs any extra code. Isn't this normal
operation already?

6. When the next ACK arrives that acknowledges previously
unacknowledged data, a TCP MUST set cwnd to ssthresh (the value
set in step 2). This is termed "deflating" the window.

Ok, in ProcessPacketAction, where you reset dupackcount:

if (tcpHeader.GetAckNumber () > m_highestRxAck)
{
m_dupAckCount = 0;
}

simply add (before the m_dupackcount=0 line):

if (m_dupAckCount >=3) // We had entered fast retransmit and inflated
cwnd
{
m_cWnd = m_ssThresh;
}

Tom Henderson

unread,
Feb 25, 2010, 2:27:23 AM2/25/10
to ns-3-...@googlegroups.com
On 2/24/10 4:18 AM, Antti M�kel� wrote:
> On Feb 8, 5:41 pm, Tom Henderson<t...@tomh.org> wrote:
>>> Actually, the native TCP implementation in NS-3 (supposed to be Tahoe)
>>> supports theFastRetransmit feature, but It does not supportFast
>>> Recovery. You can see howFastRetransmit is implemented in the method
>>> called DupAck from the class TcpSocketImpl:
>> I agree, it is probably best described as Tahoe plusFastRetransmit.
>
> I wonder how much work would be needed to include also fast recovery -
> what do you guys think?

agree-- started a tracker item 824 for this thread.

- Tom

Reply all
Reply to author
Forward
0 new messages