TCPReno Class Reference

#include <TCPReno.h>

Inheritance diagram for TCPReno:

TCPTahoeRenoFamily TCPBaseAlg TCPAlgorithm List of all members.

Detailed Description

Implements TCP Reno.


Public Member Functions

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

Protected Member Functions

virtual TCPStateVariablescreateStateVariables ()
void recalculateSlowStartThreshold ()
virtual void processRexmitTimer (TCPEventCode &event)

Protected Attributes

TCPRenoStateVariables *& state


Constructor & Destructor Documentation

TCPReno::TCPReno (  ) 

Ctor

00026                  : TCPTahoeRenoFamily(),
00027   state((TCPRenoStateVariables *&)TCPAlgorithm::state)
00028 {
00029 }


Member Function Documentation

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

Create and return a TCPRenoStateVariables object.

Implements TCPAlgorithm.

00041                                                       {
00042         return new TCPRenoStateVariables();
00043     }

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

Redefine what should happen on retransmission

Reimplemented from TCPBaseAlg.

00041 {
00042     TCPTahoeRenoFamily::processRexmitTimer(event);
00043     if (event==TCP_E_ABORT)
00044         return;
00045 
00046     // begin Slow Start (RFC2001)
00047     recalculateSlowStartThreshold();
00048     state->snd_cwnd = state->snd_mss;
00049     if (cwndVector) cwndVector->record(state->snd_cwnd);
00050     tcpEV << "Begin Slow Start: resetting cwnd to " << state->snd_cwnd
00051           << ", ssthresh=" << state->ssthresh << "\n";
00052 
00053     // Reno retransmits all data (unlike Tahoe which transmits only the segment)
00054     conn->retransmitData();
00055 }

void TCPReno::recalculateSlowStartThreshold (  )  [protected]

Utility function to recalculate ssthresh

00032 {
00033     // set ssthresh to flight size/2, but at least 2 MSS
00034     // (the formula below practically amounts to ssthresh=cwnd/2 most of the time)
00035     uint flight_size = Min(state->snd_cwnd, state->snd_wnd);
00036     state->ssthresh = Max(flight_size/2, 2*state->snd_mss);
00037     if (ssthreshVector) ssthreshVector->record(state->ssthresh);
00038 }

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

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

Reimplemented from TCPBaseAlg.

00058 {
00059     TCPTahoeRenoFamily::receivedDataAck(firstSeqAcked);
00060 
00061     if (state->dupacks>=3)
00062     {
00063         //
00064         // Perform Fast Recovery: set cwnd to ssthresh (deflating the window).
00065         //
00066         tcpEV << "Fast Recovery: setting cwnd to ssthresh=" << state->ssthresh << "\n";
00067         state->snd_cwnd = state->ssthresh;
00068         if (cwndVector) cwndVector->record(state->snd_cwnd);
00069     }
00070     else
00071     {
00072         //
00073         // Perform slow start and congestion avoidance.
00074         //
00075         if (state->snd_cwnd < state->ssthresh)
00076         {
00077             tcpEV << "cwnd<=ssthresh: Slow Start: increasing cwnd by one segment, to ";
00078 
00079             // perform Slow Start. rfc 2581: "During slow start, a TCP increments cwnd
00080             // by at most SMSS bytes for each ACK received that acknowledges new data."
00081             state->snd_cwnd += state->snd_mss;
00082 
00083             // NOTE: we could increase cwnd based on the number of bytes being
00084             // acknowledged by each arriving ACK, rather than by the number of ACKs
00085             // that arrive. This is called "Appropriate Byte Counting" (ABC) and is
00086             // described in rfc 3465. This rfc is experimental and probably not
00087             // implemented in real-life TCPs, hence it's commented out. Also, the ABC
00088             // rfc would require other modifications as well in addition to the
00089             // two lines below.
00090             //
00091             // int bytesAcked = state->snd_una - firstSeqAcked;
00092             // state->snd_cwnd += bytesAcked*state->snd_mss;
00093 
00094             if (cwndVector) cwndVector->record(state->snd_cwnd);
00095 
00096             tcpEV << "cwnd=" << state->snd_cwnd << "\n";
00097         }
00098         else
00099         {
00100             // perform Congestion Avoidance (rfc 2581)
00101             int incr = state->snd_mss * state->snd_mss / state->snd_cwnd;
00102             if (incr==0)
00103                 incr = 1;
00104             state->snd_cwnd += incr;
00105             if (cwndVector) cwndVector->record(state->snd_cwnd);
00106 
00107             //
00108             // NOTE: some implementations use extra additive constant mss/8 here
00109             // which is known to be incorrect (rfc 2581 p5)
00110             //
00111             // NOTE 2: rfc 3465 (experimental) "Appropriate Byte Counting" (ABC)
00112             // would require maintaining a bytes_acked variable here which we don't do
00113             //
00114 
00115             tcpEV << "cwnd>ssthresh: Congestion Avoidance: increasing cwnd linearly, to " << state->snd_cwnd << "\n";
00116         }
00117     }
00118 
00119     // ack and/or cwnd increase may have freed up some room in the window, try sending
00120     sendData();
00121 }

void TCPReno::receivedDuplicateAck (  )  [virtual]

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

Reimplemented from TCPBaseAlg.

00124 {
00125     TCPTahoeRenoFamily::receivedDuplicateAck();
00126 
00127     if (state->dupacks==3)
00128     {
00129         tcpEV << "Reno on dupAck=3: perform Fast Retransmit, and enter Fast Recovery:";
00130 
00131         // Fast Retransmission: retransmit missing segment without waiting
00132         // for the REXMIT timer to expire
00133         conn->retransmitOneSegment();
00134 
00135         // enter slow start
00136         // "set cwnd to ssthresh plus 3 times the segment size." (rfc 2001)
00137         recalculateSlowStartThreshold();
00138         state->snd_cwnd = state->ssthresh + 3*state->snd_mss;  // 20051129 (1)
00139         if (cwndVector) cwndVector->record(state->snd_cwnd);
00140 
00141         tcpEV << "set cwnd=" << state->snd_cwnd << ", ssthresh=" << state->ssthresh << "\n";
00142 
00143         // restart retransmission timer (with rexmit_count=0), and cancel round-trip time measurement
00144         // (see p972 "29.4 Fast Retransmit and Fast Recovery Algorithms" of
00145         // TCP/IP Illustrated, Vol2) -- but that's probably New Reno
00146         cancelEvent(rexmitTimer);
00147         startRexmitTimer();
00148         state->rtseq_sendtime = 0;
00149     }
00150     else if (state->dupacks > 3)
00151     {
00152         //
00153         // Reno: For each additional duplicate ACK received, increment cwnd by MSS.
00154         // This artificially inflates the congestion window in order to reflect the
00155         // additional segment that has left the network
00156         //
00157         state->snd_cwnd += state->snd_mss;
00158         tcpEV << "Reno on dupAck>3: Fast Recovery: inflating cwnd by MSS, new cwnd=" << state->snd_cwnd << "\n";
00159         if (cwndVector) cwndVector->record(state->snd_cwnd);
00160 
00161         // cwnd increased, try sending
00162         sendData();  // 20051129 (2)
00163     }
00164 }


Member Data Documentation

TCPRenoStateVariables*& TCPReno::state [protected]

Reimplemented from TCPTahoeRenoFamily.


The documentation for this class was generated from the following files:
Generated on Wed Apr 4 13:20:24 2007 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.7