INET Framework for OMNeT++/OMNEST
inet::tcp::TCPReno Class Reference

Implements TCP Reno. More...

#include <TCPReno.h>

Inheritance diagram for inet::tcp::TCPReno:
inet::tcp::TCPTahoeRenoFamily inet::tcp::TCPBaseAlg inet::tcp::TCPAlgorithm

Public Member Functions

 TCPReno ()
 Ctor. More...
 
virtual void receivedDataAck (uint32 firstSeqAcked) override
 Redefine what should happen when data got acked, to add congestion window management. More...
 
virtual void receivedDuplicateAck () override
 Redefine what should happen when dupAck was received, to add congestion window management. More...
 
- Public Member Functions inherited from inet::tcp::TCPTahoeRenoFamily
 TCPTahoeRenoFamily ()
 Ctor. More...
 
- Public Member Functions inherited from inet::tcp::TCPBaseAlg
 TCPBaseAlg ()
 Ctor. More...
 
virtual ~TCPBaseAlg ()
 Virtual dtor. More...
 
virtual void initialize () override
 Create timers, etc. More...
 
virtual void established (bool active) override
 Called when the connection is going to ESTABLISHED from SYN_SENT or SYN_RCVD. More...
 
virtual void connectionClosed () override
 Called when the connection closes, it should cancel all running timers. More...
 
virtual void processTimer (cMessage *timer, TCPEventCode &event) override
 Process REXMIT, PERSIST, DELAYED-ACK and KEEP-ALIVE timers. More...
 
virtual void sendCommandInvoked () override
 Called after user sent TCP_C_SEND command to us. More...
 
virtual void receivedOutOfOrderSegment () override
 Called after receiving data which are in the window, but not at its left edge (seq != rcv_nxt). More...
 
virtual void receiveSeqChanged () override
 Called after rcv_nxt got advanced, either because we received in-sequence data ("text" in RFC 793 lingo) or a FIN. More...
 
virtual void receivedAckForDataNotYetSent (uint32 seq) override
 Called after we received an ACK for data not yet sent. More...
 
virtual void ackSent () override
 Called after we sent an ACK. More...
 
virtual void dataSent (uint32 fromseq) override
 Called after we sent data. More...
 
virtual void segmentRetransmitted (uint32 fromseq, uint32 toseq) override
 Called after we retransmitted segment. More...
 
virtual void restartRexmitTimer () override
 Restart REXMIT timer. More...
 
- Public Member Functions inherited from inet::tcp::TCPAlgorithm
 TCPAlgorithm ()
 Ctor. More...
 
virtual ~TCPAlgorithm ()
 Virtual dtor. More...
 
void setConnection (TCPConnection *_conn)
 Assign this object to a TCPConnection. More...
 
TCPStateVariablesgetStateVariables ()
 Creates and returns the TCP state variables. More...
 

Protected Member Functions

virtual TCPStateVariablescreateStateVariables () override
 Create and return a TCPRenoStateVariables object. More...
 
virtual void recalculateSlowStartThreshold ()
 Utility function to recalculate ssthresh. More...
 
virtual void processRexmitTimer (TCPEventCode &event) override
 Redefine what should happen on retransmission. More...
 
- Protected Member Functions inherited from inet::tcp::TCPBaseAlg
virtual void startRexmitTimer ()
 Start REXMIT timer and initialize retransmission variables. More...
 
virtual void rttMeasurementComplete (simtime_t tSent, simtime_t tAcked)
 Update state vars with new measured RTT value. More...
 
virtual void rttMeasurementCompleteUsingTS (uint32 echoedTS) override
 Converting uint32 echoedTS to simtime_t and calling rttMeasurementComplete() to update state vars with new measured RTT value. More...
 
virtual bool sendData (bool sendCommandInvoked)
 Send data, observing Nagle's algorithm and congestion window. More...
 
cMessage * cancelEvent (cMessage *msg)
 Utility function. More...
 
virtual void processPersistTimer (TCPEventCode &event)
 
virtual void processDelayedAckTimer (TCPEventCode &event)
 
virtual void processKeepAliveTimer (TCPEventCode &event)
 

Protected Attributes

TCPRenoStateVariables *& state
 
- Protected Attributes inherited from inet::tcp::TCPTahoeRenoFamily
TCPTahoeRenoFamilyStateVariables *& state
 
- Protected Attributes inherited from inet::tcp::TCPBaseAlg
TCPBaseAlgStateVariables *& state
 
cMessage * rexmitTimer
 
cMessage * persistTimer
 
cMessage * delayedAckTimer
 
cMessage * keepAliveTimer
 
cOutVector * cwndVector
 
cOutVector * ssthreshVector
 
cOutVector * rttVector
 
cOutVector * srttVector
 
cOutVector * rttvarVector
 
cOutVector * rtoVector
 
cOutVector * numRtosVector
 
- Protected Attributes inherited from inet::tcp::TCPAlgorithm
TCPConnectionconn
 
TCPStateVariablesstate
 

Detailed Description

Implements TCP Reno.

Constructor & Destructor Documentation

inet::tcp::TCPReno::TCPReno ( )

Ctor.

31 {
32 }
TCPStateVariables * state
Definition: TCPAlgorithm.h:41
TCPTahoeRenoFamily()
Ctor.
Definition: TCPTahoeRenoFamily.cc:58
TCPRenoStateVariables *& state
Definition: TCPReno.h:40
TCPTahoeRenoFamilyStateVariables TCPRenoStateVariables
State variables for TCPReno.
Definition: TCPReno.h:32

Member Function Documentation

virtual TCPStateVariables* inet::tcp::TCPReno::createStateVariables ( )
inlineoverrideprotectedvirtual

Create and return a TCPRenoStateVariables object.

Implements inet::tcp::TCPAlgorithm.

44  {
45  return new TCPRenoStateVariables();
46  }
TCPTahoeRenoFamilyStateVariables TCPRenoStateVariables
State variables for TCPReno.
Definition: TCPReno.h:32
void inet::tcp::TCPReno::processRexmitTimer ( TCPEventCode event)
overrideprotectedvirtual

Redefine what should happen on retransmission.

Reimplemented from inet::tcp::TCPBaseAlg.

57 {
59 
60  if (event == TCP_E_ABORT)
61  return;
62 
63  // After REXMIT timeout TCP Reno should start slow start with snd_cwnd = snd_mss.
64  //
65  // If calling "retransmitData();" there is no rexmit limitation (bytesToSend > snd_cwnd)
66  // therefore "sendData();" has been modified and is called to rexmit outstanding data.
67  //
68  // RFC 2581, page 5:
69  // "Furthermore, upon a timeout cwnd MUST be set to no more than the loss
70  // window, LW, which equals 1 full-sized segment (regardless of the
71  // value of IW). Therefore, after retransmitting the dropped segment
72  // the TCP sender uses the slow start algorithm to increase the window
73  // from 1 full-sized segment to the new value of ssthresh, at which
74  // point congestion avoidance again takes over."
75 
76  // begin Slow Start (RFC 2581)
79 
80  if (cwndVector)
81  cwndVector->record(state->snd_cwnd);
82 
83  EV_INFO << "Begin Slow Start: resetting cwnd to " << state->snd_cwnd
84  << ", ssthresh=" << state->ssthresh << "\n";
85 
86  state->afterRto = true;
87 
89 }
virtual void recalculateSlowStartThreshold()
Utility function to recalculate ssthresh.
Definition: TCPReno.cc:34
virtual void retransmitOneSegment(bool called_at_rto)
Utility: retransmit one segment from snd_una.
Definition: TCPConnectionUtil.cc:802
cOutVector * cwndVector
Definition: TCPBaseAlg.h:115
virtual void processRexmitTimer(TCPEventCode &event)
Definition: TCPBaseAlg.cc:231
uint32 snd_mss
Definition: TCPConnection.h:159
Definition: TCPConnection.h:90
TCPRenoStateVariables *& state
Definition: TCPReno.h:40
bool afterRto
Definition: TCPConnection.h:213
TCPConnection * conn
Definition: TCPAlgorithm.h:40
uint32 ssthresh
slow start threshold
Definition: TCPTahoeRenoFamily.h:40
uint32 snd_cwnd
congestion window
Definition: TCPBaseAlg.h:54
void inet::tcp::TCPReno::recalculateSlowStartThreshold ( )
protectedvirtual

Utility function to recalculate ssthresh.

Referenced by processRexmitTimer(), and receivedDuplicateAck().

35 {
36  // RFC 2581, page 4:
37  // "When a TCP sender detects segment loss using the retransmission
38  // timer, the value of ssthresh MUST be set to no more than the value
39  // given in equation 3:
40  //
41  // ssthresh = max (FlightSize / 2, 2*SMSS) (3)
42  //
43  // As discussed above, FlightSize is the amount of outstanding data in
44  // the network."
45 
46  // set ssthresh to flight size / 2, but at least 2 SMSS
47  // (the formula below practically amounts to ssthresh = cwnd / 2 most of the time)
48  uint32 flight_size = std::min(state->snd_cwnd, state->snd_wnd); // FIXME TODO - Does this formula computes the amount of outstanding data?
49  // uint32 flight_size = state->snd_max - state->snd_una;
50  state->ssthresh = std::max(flight_size / 2, 2 * state->snd_mss);
51 
52  if (ssthreshVector)
53  ssthreshVector->record(state->ssthresh);
54 }
double min(const double a, const double b)
Returns the minimum of a and b.
Definition: SCTPAssociation.h:270
double max(double a, double b)
Returns the greater of the given parameters.
Definition: INETMath.h:161
uint32 snd_wnd
Definition: TCPConnection.h:167
uint32 snd_mss
Definition: TCPConnection.h:159
TCPRenoStateVariables *& state
Definition: TCPReno.h:40
uint32_t uint32
Definition: Compat.h:30
cOutVector * ssthreshVector
Definition: TCPBaseAlg.h:116
uint32 ssthresh
slow start threshold
Definition: TCPTahoeRenoFamily.h:40
uint32 snd_cwnd
congestion window
Definition: TCPBaseAlg.h:54
void inet::tcp::TCPReno::receivedDataAck ( uint32  firstSeqAcked)
overridevirtual

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

Reimplemented from inet::tcp::TCPBaseAlg.

92 {
94 
95  if (state->dupacks >= DUPTHRESH) { // DUPTHRESH = 3
96  //
97  // Perform Fast Recovery: set cwnd to ssthresh (deflating the window).
98  //
99  EV_INFO << "Fast Recovery: setting cwnd to ssthresh=" << state->ssthresh << "\n";
101 
102  if (cwndVector)
103  cwndVector->record(state->snd_cwnd);
104  }
105  else {
106  //
107  // Perform slow start and congestion avoidance.
108  //
109  if (state->snd_cwnd < state->ssthresh) {
110  EV_INFO << "cwnd <= ssthresh: Slow Start: increasing cwnd by one SMSS bytes to ";
111 
112  // perform Slow Start. RFC 2581: "During slow start, a TCP increments cwnd
113  // by at most SMSS bytes for each ACK received that acknowledges new data."
115 
116  // Note: we could increase cwnd based on the number of bytes being
117  // acknowledged by each arriving ACK, rather than by the number of ACKs
118  // that arrive. This is called "Appropriate Byte Counting" (ABC) and is
119  // described in RFC 3465. This RFC is experimental and probably not
120  // implemented in real-life TCPs, hence it's commented out. Also, the ABC
121  // RFC would require other modifications as well in addition to the
122  // two lines below.
123  //
124  // int bytesAcked = state->snd_una - firstSeqAcked;
125  // state->snd_cwnd += bytesAcked * state->snd_mss;
126 
127  if (cwndVector)
128  cwndVector->record(state->snd_cwnd);
129 
130  EV_INFO << "cwnd=" << state->snd_cwnd << "\n";
131  }
132  else {
133  // perform Congestion Avoidance (RFC 2581)
135 
136  if (incr == 0)
137  incr = 1;
138 
139  state->snd_cwnd += incr;
140 
141  if (cwndVector)
142  cwndVector->record(state->snd_cwnd);
143 
144  //
145  // Note: some implementations use extra additive constant mss / 8 here
146  // which is known to be incorrect (RFC 2581 p5)
147  //
148  // Note 2: RFC 3465 (experimental) "Appropriate Byte Counting" (ABC)
149  // would require maintaining a bytes_acked variable here which we don't do
150  //
151 
152  EV_INFO << "cwnd > ssthresh: Congestion Avoidance: increasing cwnd linearly, to " << state->snd_cwnd << "\n";
153  }
154  }
155 
157  // RFC 3517, page 7: "Once a TCP is in the loss recovery phase the following procedure MUST
158  // be used for each arriving ACK:
159  //
160  // (A) An incoming cumulative ACK for a sequence number greater than
161  // RecoveryPoint signals the end of loss recovery and the loss
162  // recovery phase MUST be terminated. Any information contained in
163  // the scoreboard for sequence numbers greater than the new value of
164  // HighACK SHOULD NOT be cleared when leaving the loss recovery
165  // phase."
167  EV_INFO << "Loss Recovery terminated.\n";
168  state->lossRecovery = false;
169  }
170  // RFC 3517, page 7: "(B) Upon receipt of an ACK that does not cover RecoveryPoint the
171  //following actions MUST be taken:
172  //
173  // (B.1) Use Update () to record the new SACK information conveyed
174  // by the incoming ACK.
175  //
176  // (B.2) Use SetPipe () to re-calculate the number of octets still
177  // in the network."
178  else {
179  // update of scoreboard (B.1) has already be done in readHeaderOptions()
180  conn->setPipe();
181 
182  // RFC 3517, page 7: "(C) If cwnd - pipe >= 1 SMSS the sender SHOULD transmit one or more
183  // segments as follows:"
184  if (((int)state->snd_cwnd - (int)state->pipe) >= (int)state->snd_mss) // Note: Typecast needed to avoid prohibited transmissions
186  }
187  }
188 
189  // RFC 3517, pages 7 and 8: "5.1 Retransmission Timeouts
190  // (...)
191  // If there are segments missing from the receiver's buffer following
192  // processing of the retransmitted segment, the corresponding ACK will
193  // contain SACK information. In this case, a TCP sender SHOULD use this
194  // SACK information when determining what data should be sent in each
195  // segment of the slow start. The exact algorithm for this selection is
196  // not specified in this document (specifically NextSeg () is
197  // inappropriate during slow start after an RTO). A relatively
198  // straightforward approach to "filling in" the sequence space reported
199  // as missing should be a reasonable approach."
200  sendData(false);
201 }
bool seqGE(uint32 a, uint32 b)
Definition: TCPSegment.h:35
cOutVector * cwndVector
Definition: TCPBaseAlg.h:115
virtual void sendDataDuringLossRecoveryPhase(uint32 congestionWindow)
Utility: send data during Loss Recovery phase (if SACK is enabled).
Definition: TCPConnectionSackUtil.cc:344
uint32 pipe
Definition: TCPConnection.h:244
uint32 recoveryPoint
Definition: TCPConnection.h:245
virtual void receivedDataAck(uint32 firstSeqAcked) override
Called after we received an ACK which acked some data (that is, we could advance snd_una).
Definition: TCPBaseAlg.cc:529
uint32 snd_mss
Definition: TCPConnection.h:159
bool sack_enabled
Definition: TCPConnection.h:235
uint32 dupacks
Definition: TCPConnection.h:255
#define DUPTHRESH
Definition: TCPConnection.h:126
uint32 snd_una
Definition: TCPConnection.h:164
TCPRenoStateVariables *& state
Definition: TCPReno.h:40
uint32_t uint32
Definition: Compat.h:30
virtual void setPipe()
For SACK TCP.
Definition: TCPConnectionSackUtil.cc:153
TCPConnection * conn
Definition: TCPAlgorithm.h:40
bool lossRecovery
Definition: TCPConnection.h:248
uint32 ssthresh
slow start threshold
Definition: TCPTahoeRenoFamily.h:40
uint32 snd_cwnd
congestion window
Definition: TCPBaseAlg.h:54
virtual bool sendData(bool sendCommandInvoked)
Send data, observing Nagle&#39;s algorithm and congestion window.
Definition: TCPBaseAlg.cc:429
void inet::tcp::TCPReno::receivedDuplicateAck ( )
overridevirtual

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

Reimplemented from inet::tcp::TCPBaseAlg.

204 {
206 
207  if (state->dupacks == DUPTHRESH) { // DUPTHRESH = 3
208  EV_INFO << "Reno on dupAcks == DUPTHRESH(=3): perform Fast Retransmit, and enter Fast Recovery:";
209 
210  if (state->sack_enabled) {
211  // RFC 3517, page 6: "When a TCP sender receives the duplicate ACK corresponding to
212  // DupThresh ACKs, the scoreboard MUST be updated with the new SACK
213  // information (via Update ()). If no previous loss event has occurred
214  // on the connection or the cumulative acknowledgment point is beyond
215  // the last value of RecoveryPoint, a loss recovery phase SHOULD be
216  // initiated, per the fast retransmit algorithm outlined in [RFC2581].
217  // The following steps MUST be taken:
218  //
219  // (1) RecoveryPoint = HighData
220  //
221  // When the TCP sender receives a cumulative ACK for this data octet
222  // the loss recovery phase is terminated."
223 
224  // RFC 3517, page 8: "If an RTO occurs during loss recovery as specified in this document,
225  // RecoveryPoint MUST be set to HighData. Further, the new value of
226  // RecoveryPoint MUST be preserved and the loss recovery algorithm
227  // outlined in this document MUST be terminated. In addition, a new
228  // recovery phase (as described in section 5) MUST NOT be initiated
229  // until HighACK is greater than or equal to the new value of
230  // RecoveryPoint."
231  if (state->recoveryPoint == 0 || seqGE(state->snd_una, state->recoveryPoint)) { // HighACK = snd_una
232  state->recoveryPoint = state->snd_max; // HighData = snd_max
233  state->lossRecovery = true;
234  EV_DETAIL << " recoveryPoint=" << state->recoveryPoint;
235  }
236  }
237  // RFC 2581, page 5:
238  // "After the fast retransmit algorithm sends what appears to be the
239  // missing segment, the "fast recovery" algorithm governs the
240  // transmission of new data until a non-duplicate ACK arrives.
241  // (...) the TCP sender can continue to transmit new
242  // segments (although transmission must continue using a reduced cwnd)."
243 
244  // enter Fast Recovery
246  // "set cwnd to ssthresh plus 3 * SMSS." (RFC 2581)
247  state->snd_cwnd = state->ssthresh + 3 * state->snd_mss; // 20051129 (1)
248 
249  if (cwndVector)
250  cwndVector->record(state->snd_cwnd);
251 
252  EV_DETAIL << " set cwnd=" << state->snd_cwnd << ", ssthresh=" << state->ssthresh << "\n";
253 
254  // Fast Retransmission: retransmit missing segment without waiting
255  // for the REXMIT timer to expire
256  conn->retransmitOneSegment(false);
257 
258  // Do not restart REXMIT timer.
259  // Note: Restart of REXMIT timer on retransmission is not part of RFC 2581, however optional in RFC 3517 if sent during recovery.
260  // Resetting the REXMIT timer is discussed in RFC 2582/3782 (NewReno) and RFC 2988.
261 
262  if (state->sack_enabled) {
263  // RFC 3517, page 7: "(4) Run SetPipe ()
264  //
265  // Set a "pipe" variable to the number of outstanding octets
266  // currently "in the pipe"; this is the data which has been sent by
267  // the TCP sender but for which no cumulative or selective
268  // acknowledgment has been received and the data has not been
269  // determined to have been dropped in the network. It is assumed
270  // that the data is still traversing the network path."
271  conn->setPipe();
272  // RFC 3517, page 7: "(5) In order to take advantage of potential additional available
273  // cwnd, proceed to step (C) below."
274  if (state->lossRecovery) {
275  // RFC 3517, page 9: "Therefore we give implementers the latitude to use the standard
276  // [RFC2988] style RTO management or, optionally, a more careful variant
277  // that re-arms the RTO timer on each retransmission that is sent during
278  // recovery MAY be used. This provides a more conservative timer than
279  // specified in [RFC2988], and so may not always be an attractive
280  // alternative. However, in some cases it may prevent needless
281  // retransmissions, go-back-N transmission and further reduction of the
282  // congestion window."
283  // Note: Restart of REXMIT timer on retransmission is not part of RFC 2581, however optional in RFC 3517 if sent during recovery.
284  EV_INFO << "Retransmission sent during recovery, restarting REXMIT timer.\n";
286 
287  // RFC 3517, page 7: "(C) If cwnd - pipe >= 1 SMSS the sender SHOULD transmit one or more
288  // segments as follows:"
289  if (((int)state->snd_cwnd - (int)state->pipe) >= (int)state->snd_mss) // Note: Typecast needed to avoid prohibited transmissions
291  }
292  }
293 
294  // try to transmit new segments (RFC 2581)
295  sendData(false);
296  }
297  else if (state->dupacks > DUPTHRESH) { // DUPTHRESH = 3
298  //
299  // Reno: For each additional duplicate ACK received, increment cwnd by SMSS.
300  // This artificially inflates the congestion window in order to reflect the
301  // additional segment that has left the network
302  //
304  EV_DETAIL << "Reno on dupAcks > DUPTHRESH(=3): Fast Recovery: inflating cwnd by SMSS, new cwnd=" << state->snd_cwnd << "\n";
305 
306  if (cwndVector)
307  cwndVector->record(state->snd_cwnd);
308 
309  // Note: Steps (A) - (C) of RFC 3517, page 7 ("Once a TCP is in the loss recovery phase the following procedure MUST be used for each arriving ACK")
310  // should not be used here!
311 
312  // RFC 3517, pages 7 and 8: "5.1 Retransmission Timeouts
313  // (...)
314  // If there are segments missing from the receiver's buffer following
315  // processing of the retransmitted segment, the corresponding ACK will
316  // contain SACK information. In this case, a TCP sender SHOULD use this
317  // SACK information when determining what data should be sent in each
318  // segment of the slow start. The exact algorithm for this selection is
319  // not specified in this document (specifically NextSeg () is
320  // inappropriate during slow start after an RTO). A relatively
321  // straightforward approach to "filling in" the sequence space reported
322  // as missing should be a reasonable approach."
323  sendData(false);
324  }
325 }
bool seqGE(uint32 a, uint32 b)
Definition: TCPSegment.h:35
virtual void recalculateSlowStartThreshold()
Utility function to recalculate ssthresh.
Definition: TCPReno.cc:34
virtual void retransmitOneSegment(bool called_at_rto)
Utility: retransmit one segment from snd_una.
Definition: TCPConnectionUtil.cc:802
cOutVector * cwndVector
Definition: TCPBaseAlg.h:115
virtual void sendDataDuringLossRecoveryPhase(uint32 congestionWindow)
Utility: send data during Loss Recovery phase (if SACK is enabled).
Definition: TCPConnectionSackUtil.cc:344
uint32 pipe
Definition: TCPConnection.h:244
uint32 recoveryPoint
Definition: TCPConnection.h:245
uint32 snd_mss
Definition: TCPConnection.h:159
bool sack_enabled
Definition: TCPConnection.h:235
uint32 dupacks
Definition: TCPConnection.h:255
#define DUPTHRESH
Definition: TCPConnection.h:126
virtual void restartRexmitTimer() override
Restart REXMIT timer.
Definition: TCPBaseAlg.cc:674
uint32 snd_una
Definition: TCPConnection.h:164
TCPRenoStateVariables *& state
Definition: TCPReno.h:40
virtual void setPipe()
For SACK TCP.
Definition: TCPConnectionSackUtil.cc:153
virtual void receivedDuplicateAck() override
Called after we received a duplicate ACK (that is: ackNo == snd_una, no data in segment, segment doesn&#39;t carry window update, and also, we have unacked data).
Definition: TCPBaseAlg.cc:611
TCPConnection * conn
Definition: TCPAlgorithm.h:40
bool lossRecovery
Definition: TCPConnection.h:248
uint32 ssthresh
slow start threshold
Definition: TCPTahoeRenoFamily.h:40
uint32 snd_max
Definition: TCPConnection.h:166
uint32 snd_cwnd
congestion window
Definition: TCPBaseAlg.h:54
virtual bool sendData(bool sendCommandInvoked)
Send data, observing Nagle&#39;s algorithm and congestion window.
Definition: TCPBaseAlg.cc:429

Member Data Documentation


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