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 TCPStateVariablescreateStateVariables ()
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: