#include <TCPTahoe.h>
Inheritance diagram for TCPTahoe:
Public Member Functions | |
TCPTahoe () | |
virtual void | receivedDataAck (uint32 firstSeqAcked) |
virtual void | receivedDuplicateAck () |
Protected Member Functions | |
virtual TCPStateVariables * | createStateVariables () |
void | recalculateSlowStartThreshold () |
virtual void | processRexmitTimer (TCPEventCode &event) |
Protected Attributes | |
TCPTahoeStateVariables *& | state |
TCPTahoe::TCPTahoe | ( | ) |
Ctor
00026 : TCPTahoeRenoFamily(), 00027 state((TCPTahoeStateVariables *&)TCPAlgorithm::state) 00028 { 00029 }
virtual TCPStateVariables* TCPTahoe::createStateVariables | ( | ) | [inline, protected, virtual] |
Create and return a TCPTahoeStateVariables object.
Implements TCPAlgorithm.
00042 { 00043 return new TCPTahoeStateVariables(); 00044 }
void TCPTahoe::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 // Tahoe retransmits only one segment at the front of the queue 00054 conn->retransmitOneSegment(); 00055 }
void TCPTahoe::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 TCPTahoe::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 // 00062 // Perform slow start and congestion avoidance. 00063 // 00064 if (state->snd_cwnd < state->ssthresh) 00065 { 00066 tcpEV << "cwnd<=ssthresh: Slow Start: increasing cwnd by one segment, to "; 00067 00068 // perform Slow Start. rfc 2581: "During slow start, a TCP increments cwnd 00069 // by at most SMSS bytes for each ACK received that acknowledges new data." 00070 state->snd_cwnd += state->snd_mss; 00071 00072 // NOTE: we could increase cwnd based on the number of bytes being 00073 // acknowledged by each arriving ACK, rather than by the number of ACKs 00074 // that arrive. This is called "Appropriate Byte Counting" (ABC) and is 00075 // described in rfc 3465 (experimental). 00076 // 00077 // int bytesAcked = state->snd_una - firstSeqAcked; 00078 // state->snd_cwnd += bytesAcked; 00079 00080 if (cwndVector) cwndVector->record(state->snd_cwnd); 00081 00082 tcpEV << "cwnd=" << state->snd_cwnd << "\n"; 00083 } 00084 else 00085 { 00086 // perform Congestion Avoidance (rfc 2581) 00087 int incr = state->snd_mss * state->snd_mss / state->snd_cwnd; 00088 if (incr==0) 00089 incr = 1; 00090 state->snd_cwnd += incr; 00091 if (cwndVector) cwndVector->record(state->snd_cwnd); 00092 00093 // 00094 // NOTE: some implementations use extra additive constant mss/8 here 00095 // which is known to be incorrect (rfc 2581 p5) 00096 // 00097 // NOTE 2: rfc 3465 (experimental) "Appropriate Byte Counting" (ABC) 00098 // would require maintaining a bytes_acked variable here which we don't do 00099 // 00100 00101 tcpEV << "cwnd>ssthresh: Congestion Avoidance: increasing cwnd linearly, to " << state->snd_cwnd << "\n"; 00102 } 00103 00104 // ack and/or cwnd increase may have freed up some room in the window, try sending 00105 sendData(); 00106 }
void TCPTahoe::receivedDuplicateAck | ( | ) | [virtual] |
Redefine what should happen when dupAck was received, to add congestion window management
Reimplemented from TCPBaseAlg.
00109 { 00110 TCPTahoeRenoFamily::receivedDuplicateAck(); 00111 00112 if (state->dupacks==3) 00113 { 00114 tcpEV << "Tahoe on dupAck=3: perform Fast Retransmit, and enter Slow Start:\n"; 00115 00116 // Fast Retransmission: retransmit missing segment without waiting 00117 // for the REXMIT timer to expire 00118 conn->retransmitOneSegment(); 00119 00120 // enter Slow Start 00121 recalculateSlowStartThreshold(); 00122 state->snd_cwnd = state->snd_mss; 00123 if (cwndVector) cwndVector->record(state->snd_cwnd); 00124 00125 tcpEV << "Set cwnd=" << state->snd_cwnd << ", ssthresh=" << state->ssthresh << "\n"; 00126 00127 // FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME 00128 // double-check if Tahoe really restarts REXMIT timer here 00129 // 00130 // restart retransmission timer (with rexmit_count=0), and cancel round-trip time measurement 00131 // (see p972 "29.4 Fast Retransmit and Fast Recovery Algorithms" of 00132 // TCP/IP Illustrated, Vol2) -- but that's probably New Reno 00133 cancelEvent(rexmitTimer); 00134 startRexmitTimer(); 00135 state->rtseq_sendtime = 0; 00136 } 00137 }
TCPTahoeStateVariables*& TCPTahoe::state [protected] |
Reimplemented from TCPTahoeRenoFamily.