Public Member Functions | Protected Member Functions | Protected Attributes

tcp_old::TCPReno Class Reference

#include <TCPReno_old.h>

Inheritance diagram for tcp_old::TCPReno:
tcp_old::TCPTahoeRenoFamily tcp_old::TCPBaseAlg tcp_old::TCPAlgorithm

List of all members.

Public Member Functions

 TCPReno ()
virtual void receivedDataAck (uint32 firstSeqAcked)
virtual void receivedDuplicateAck ()

Protected Member Functions

virtual TCPStateVariables * createStateVariables ()
virtual void recalculateSlowStartThreshold ()
virtual void processRexmitTimer (TCPEventCode &event)

Protected Attributes

TCPRenoStateVariables *& state

Detailed Description

Implements TCP Reno.

Definition at line 35 of file TCPReno_old.h.


Constructor & Destructor Documentation

TCPReno::TCPReno (  ) 

Member Function Documentation

virtual TCPStateVariables* tcp_old::TCPReno::createStateVariables (  )  [inline, protected, virtual]

Create and return a TCPRenoStateVariables object.

Implements tcp_old::TCPAlgorithm.

Definition at line 41 of file TCPReno_old.h.

                                                      {
        return new TCPRenoStateVariables();
    }

void TCPReno::processRexmitTimer ( TCPEventCode &  event  )  [protected, virtual]

Redefine what should happen on retransmission

Reimplemented from tcp_old::TCPBaseAlg.

Definition at line 41 of file old/flavours/TCPReno.cc.

{
    TCPTahoeRenoFamily::processRexmitTimer(event);
    if (event==TCP_E_ABORT)
        return;

    // begin Slow Start (RFC 2581)
    recalculateSlowStartThreshold();
    state->snd_cwnd = state->snd_mss;
    if (cwndVector) cwndVector->record(state->snd_cwnd);
    tcpEV << "Begin Slow Start: resetting cwnd to " << state->snd_cwnd
          << ", ssthresh=" << state->ssthresh << "\n";

    state->afterRto = true;

    // Reno retransmits all data (unlike Tahoe which transmits only the segment)
    // conn->retransmitData();
    // After REXMIT timeout TCP Reno should start slow start with snd_cwnd = snd_mss.
    // If calling "retransmitData();" there is no rexmit limitation (bytesToSend > snd_cwnd)
    // therefore "sendData();" has been modified and is called to rexmit outstanding data.
    conn->retransmitOneSegment(true);
}

void TCPReno::recalculateSlowStartThreshold (  )  [protected, virtual]

Utility function to recalculate ssthresh

Definition at line 32 of file old/flavours/TCPReno.cc.

Referenced by processRexmitTimer(), and receivedDuplicateAck().

{
    // set ssthresh to flight size/2, but at least 2 MSS
    // (the formula below practically amounts to ssthresh=cwnd/2 most of the time)
    uint flight_size = std::min(state->snd_cwnd, state->snd_wnd);
    state->ssthresh = std::max(flight_size/2, 2*state->snd_mss);
    if (ssthreshVector) ssthreshVector->record(state->ssthresh);
}

void TCPReno::receivedDataAck ( uint32  firstSeqAcked  )  [virtual]

Redefine what should happen when data got acked, to add congestion window management

Reimplemented from tcp_old::TCPBaseAlg.

Definition at line 64 of file old/flavours/TCPReno.cc.

{
    TCPTahoeRenoFamily::receivedDataAck(firstSeqAcked);

    if (state->dupacks>=3)
    {
        //
        // Perform Fast Recovery: set cwnd to ssthresh (deflating the window).
        //
        tcpEV << "Fast Recovery: setting cwnd to ssthresh=" << state->ssthresh << "\n";
        state->snd_cwnd = state->ssthresh;
        if (cwndVector) cwndVector->record(state->snd_cwnd);
    }
    else
    {
        //
        // Perform slow start and congestion avoidance.
        //
        if (state->snd_cwnd < state->ssthresh)
        {
            tcpEV << "cwnd<=ssthresh: Slow Start: increasing cwnd by one segment, to ";

            // perform Slow Start. rfc 2581: "During slow start, a TCP increments cwnd
            // by at most SMSS bytes for each ACK received that acknowledges new data."
            state->snd_cwnd += state->snd_mss;

            // NOTE: we could increase cwnd based on the number of bytes being
            // acknowledged by each arriving ACK, rather than by the number of ACKs
            // that arrive. This is called "Appropriate Byte Counting" (ABC) and is
            // described in rfc 3465. This rfc is experimental and probably not
            // implemented in real-life TCPs, hence it's commented out. Also, the ABC
            // rfc would require other modifications as well in addition to the
            // two lines below.
            //
            // int bytesAcked = state->snd_una - firstSeqAcked;
            // state->snd_cwnd += bytesAcked*state->snd_mss;

            if (cwndVector) cwndVector->record(state->snd_cwnd);

            tcpEV << "cwnd=" << state->snd_cwnd << "\n";
        }
        else
        {
            // perform Congestion Avoidance (rfc 2581)
            int incr = state->snd_mss * state->snd_mss / state->snd_cwnd;
            if (incr==0)
                incr = 1;
            state->snd_cwnd += incr;
            if (cwndVector) cwndVector->record(state->snd_cwnd);

            //
            // NOTE: some implementations use extra additive constant mss/8 here
            // which is known to be incorrect (rfc 2581 p5)
            //
            // NOTE 2: rfc 3465 (experimental) "Appropriate Byte Counting" (ABC)
            // would require maintaining a bytes_acked variable here which we don't do
            //

            tcpEV << "cwnd>ssthresh: Congestion Avoidance: increasing cwnd linearly, to " << state->snd_cwnd << "\n";
        }
    }

    // ack and/or cwnd increase may have freed up some room in the window, try sending
    sendData();
}

void TCPReno::receivedDuplicateAck (  )  [virtual]

Redefine what should happen when dupAck was received, to add congestion window management

Reimplemented from tcp_old::TCPBaseAlg.

Definition at line 130 of file old/flavours/TCPReno.cc.

{
    TCPTahoeRenoFamily::receivedDuplicateAck();

    if (state->dupacks==3)
    {
        tcpEV << "Reno on dupAck=3: perform Fast Retransmit, and enter Fast Recovery:";

        // enter slow start
        // "set cwnd to ssthresh plus 3 times the segment size." (rfc 2001)
        recalculateSlowStartThreshold();
        state->snd_cwnd = state->ssthresh + 3*state->snd_mss;  // 20051129 (1)
        if (cwndVector) cwndVector->record(state->snd_cwnd);

        tcpEV << "set cwnd=" << state->snd_cwnd << ", ssthresh=" << state->ssthresh << "\n";

        // Fast Retransmission: retransmit missing segment without waiting
        // for the REXMIT timer to expire
        conn->retransmitOneSegment(false);

        // Do not restart REXMIT timer.
        // Note: Restart of REXMIT timer on retransmission is not part of RFC 2581, however optional in RFC 3517 if sent during recovery.
        // Resetting the REXMIT timer is discussed in RFC 2582/3782 (NewReno) and RFC 2988.
    }
    else if (state->dupacks > 3)
    {
        //
        // Reno: For each additional duplicate ACK received, increment cwnd by MSS.
        // This artificially inflates the congestion window in order to reflect the
        // additional segment that has left the network
        //
        state->snd_cwnd += state->snd_mss;
        tcpEV << "Reno on dupAck>3: Fast Recovery: inflating cwnd by MSS, new cwnd=" << state->snd_cwnd << "\n";
        if (cwndVector) cwndVector->record(state->snd_cwnd);

        // cwnd increased, try sending
        sendData();  // 20051129 (2)
    }
}


Member Data Documentation


The documentation for this class was generated from the following files: