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

Includes basic TCP algorithms: adaptive retransmission, PERSIST timer, keep-alive, delayed acks – EXCLUDING congestion control. More...

#include <TCPBaseAlg.h>

Inheritance diagram for inet::tcp::TCPBaseAlg:
inet::tcp::TCPAlgorithm inet::tcp::TCPNoCongestionControl inet::tcp::TCPTahoeRenoFamily inet::tcp::TCPVegas inet::tcp::TCPWestwood inet::tcp::TCPNewReno inet::tcp::TCPReno inet::tcp::TCPTahoe

Public Member Functions

 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 receivedDataAck (uint32 firstSeqAcked) override
 Called after we received an ACK which acked some data (that is, we could advance snd_una). More...
 
virtual void receivedDuplicateAck () override
 Called after we received a duplicate ACK (that is: ackNo == snd_una, no data in segment, segment doesn't carry window update, and also, we have unacked data). 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 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...
 
Process REXMIT, PERSIST, DELAYED-ACK and KEEP-ALIVE timers
virtual void processRexmitTimer (TCPEventCode &event)
 
virtual void processPersistTimer (TCPEventCode &event)
 
virtual void processDelayedAckTimer (TCPEventCode &event)
 
virtual void processKeepAliveTimer (TCPEventCode &event)
 
- Protected Member Functions inherited from inet::tcp::TCPAlgorithm
virtual TCPStateVariablescreateStateVariables ()=0
 Create state block (TCB) used by this TCP variant. More...
 

Protected Attributes

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

Includes basic TCP algorithms: adaptive retransmission, PERSIST timer, keep-alive, delayed acks – EXCLUDING congestion control.

Congestion control is implemented in subclasses such as TCPTahoeAlg or TCPRenoAlg.

Implements:

  • delayed ACK algorithm (RFC 1122)
  • Jacobson's and Karn's algorithms for adaptive retransmission
  • Nagle's algorithm (RFC 896) to prevent silly window syndrome
  • Increased Initial Window (RFC 3390)
  • PERSIST timer

To be done:

  • KEEP-ALIVE timer

Note: currently the timers and time calculations are done in double and NOT in Unix (200ms or 500ms) ticks. It's possible to write another TCPAlgorithm which uses ticks (or rather, factor out timer handling to separate methods, and redefine only those).

Congestion window is set to SMSS when the connection is established, and not touched after that. Subclasses may redefine any of the virtual functions here to add their congestion control code.

Constructor & Destructor Documentation

inet::tcp::TCPBaseAlg::TCPBaseAlg ( )

Ctor.

98  : TCPAlgorithm(),
99  state((TCPBaseAlgStateVariables *&)TCPAlgorithm::state)
100 {
103 }
cOutVector * rttvarVector
Definition: TCPBaseAlg.h:119
cOutVector * srttVector
Definition: TCPBaseAlg.h:118
cOutVector * cwndVector
Definition: TCPBaseAlg.h:115
TCPStateVariables * state
Definition: TCPAlgorithm.h:41
cOutVector * rttVector
Definition: TCPBaseAlg.h:117
TCPAlgorithm()
Ctor.
Definition: TCPAlgorithm.h:55
TCPBaseAlgStateVariables *& state
Definition: TCPBaseAlg.h:108
cMessage * rexmitTimer
Definition: TCPBaseAlg.h:110
cMessage * delayedAckTimer
Definition: TCPBaseAlg.h:112
cMessage * persistTimer
Definition: TCPBaseAlg.h:111
cOutVector * ssthreshVector
Definition: TCPBaseAlg.h:116
cOutVector * rtoVector
Definition: TCPBaseAlg.h:120
cOutVector * numRtosVector
Definition: TCPBaseAlg.h:121
cMessage * keepAliveTimer
Definition: TCPBaseAlg.h:113
inet::tcp::TCPBaseAlg::~TCPBaseAlg ( )
virtual

Virtual dtor.

106 {
107  // Note: don't delete "state" here, it'll be deleted from TCPConnection
108 
109  // cancel and delete timers
110  if (rexmitTimer)
111  delete cancelEvent(rexmitTimer);
112  if (persistTimer)
113  delete cancelEvent(persistTimer);
114  if (delayedAckTimer)
116  if (keepAliveTimer)
117  delete cancelEvent(keepAliveTimer);
118 
119  // delete statistics objects
120  delete cwndVector;
121  delete ssthreshVector;
122  delete rttVector;
123  delete srttVector;
124  delete rttvarVector;
125  delete rtoVector;
126  delete numRtosVector;
127 }
cOutVector * rttvarVector
Definition: TCPBaseAlg.h:119
cOutVector * srttVector
Definition: TCPBaseAlg.h:118
cOutVector * cwndVector
Definition: TCPBaseAlg.h:115
cOutVector * rttVector
Definition: TCPBaseAlg.h:117
cMessage * rexmitTimer
Definition: TCPBaseAlg.h:110
cMessage * delayedAckTimer
Definition: TCPBaseAlg.h:112
cMessage * persistTimer
Definition: TCPBaseAlg.h:111
cOutVector * ssthreshVector
Definition: TCPBaseAlg.h:116
cOutVector * rtoVector
Definition: TCPBaseAlg.h:120
cOutVector * numRtosVector
Definition: TCPBaseAlg.h:121
cMessage * keepAliveTimer
Definition: TCPBaseAlg.h:113
cMessage * cancelEvent(cMessage *msg)
Utility function.
Definition: TCPBaseAlg.h:156

Member Function Documentation

void inet::tcp::TCPBaseAlg::ackSent ( )
overridevirtual

Called after we sent an ACK.

This hook can be used to cancel the delayed-ACK timer.

Implements inet::tcp::TCPAlgorithm.

640 {
641  state->full_sized_segment_counter = 0; // reset counter
642  state->ack_now = false; // reset flag
643  state->last_ack_sent = state->rcv_nxt; // update last_ack_sent, needed for TS option
644  // if delayed ACK timer is running, cancel it
645  if (delayedAckTimer->isScheduled())
647 }
uint32 full_sized_segment_counter
Definition: TCPConnection.h:203
uint32 last_ack_sent
Definition: TCPConnection.h:230
uint32 rcv_nxt
Definition: TCPConnection.h:174
TCPBaseAlgStateVariables *& state
Definition: TCPBaseAlg.h:108
cMessage * delayedAckTimer
Definition: TCPBaseAlg.h:112
bool ack_now
Definition: TCPConnection.h:204
cMessage * cancelEvent(cMessage *msg)
Utility function.
Definition: TCPBaseAlg.h:156
cMessage* inet::tcp::TCPBaseAlg::cancelEvent ( cMessage *  msg)
inlineprotected

Utility function.

Referenced by ackSent(), connectionClosed(), receivedDataAck(), restartRexmitTimer(), and ~TCPBaseAlg().

156 { return conn->getTcpMain()->cancelEvent(msg); }
TCP * getTcpMain()
Definition: TCPConnection.h:609
TCPConnection * conn
Definition: TCPAlgorithm.h:40
void inet::tcp::TCPBaseAlg::connectionClosed ( )
overridevirtual

Called when the connection closes, it should cancel all running timers.

Implements inet::tcp::TCPAlgorithm.

210 {
215 }
cMessage * rexmitTimer
Definition: TCPBaseAlg.h:110
cMessage * delayedAckTimer
Definition: TCPBaseAlg.h:112
cMessage * persistTimer
Definition: TCPBaseAlg.h:111
cMessage * keepAliveTimer
Definition: TCPBaseAlg.h:113
cMessage * cancelEvent(cMessage *msg)
Utility function.
Definition: TCPBaseAlg.h:156
void inet::tcp::TCPBaseAlg::dataSent ( uint32  fromseq)
overridevirtual

Called after we sent data.

This hook can be used to schedule the retransmission timer, to start round-trip time measurement, etc. The argument is the seqno of the first byte sent.

Implements inet::tcp::TCPAlgorithm.

Reimplemented in inet::tcp::TCPVegas, and inet::tcp::TCPWestwood.

Referenced by inet::tcp::TCPWestwood::dataSent(), and inet::tcp::TCPVegas::dataSent().

650 {
651  // if retransmission timer not running, schedule it
652  if (!rexmitTimer->isScheduled()) {
653  EV_INFO << "Starting REXMIT timer\n";
655  }
656 
657  if (!state->ts_enabled) {
658  // start round-trip time measurement (if not already running)
659  if (state->rtseq_sendtime == 0) {
660  // remember this sequence number and when it was sent
661  state->rtseq = fromseq;
662  state->rtseq_sendtime = simTime();
663  EV_DETAIL << "Starting rtt measurement on seq=" << state->rtseq << "\n";
664  }
665  }
666 
667  state->time_last_data_sent = simTime();
668 }
bool ts_enabled
Definition: TCPConnection.h:226
TCPBaseAlgStateVariables *& state
Definition: TCPBaseAlg.h:108
uint32 rtseq
round-trip time measurements
Definition: TCPBaseAlg.h:59
cMessage * rexmitTimer
Definition: TCPBaseAlg.h:110
virtual void startRexmitTimer()
Start REXMIT timer and initialize retransmission variables.
Definition: TCPBaseAlg.cc:359
simtime_t rtseq_sendtime
time when rtseq was sent (0 if RTT measurement is not running)
Definition: TCPBaseAlg.h:60
simtime_t time_last_data_sent
Definition: TCPConnection.h:231
void inet::tcp::TCPBaseAlg::established ( bool  active)
overridevirtual

Called when the connection is going to ESTABLISHED from SYN_SENT or SYN_RCVD.

This is a place to initialize some variables (e.g. set cwnd to the MSS learned during connection setup). If we are on the active side, here we also have to finish the 3-way connection setup procedure by sending an ACK, possibly piggybacked on data.

Implements inet::tcp::TCPAlgorithm.

155 {
156  // initialize cwnd (we may learn SMSS during connection setup)
157 
158  // RFC 3390, page 2: "The upper bound for the initial window is given more precisely in
159  // (1):
160  //
161  // min (4*MSS, max (2*MSS, 4380 bytes)) (1)
162  //
163  // Note: Sending a 1500 byte packet indicates a maximum segment size
164  // (MSS) of 1460 bytes (assuming no IP or TCP options). Therefore,
165  // limiting the initial window's MSS to 4380 bytes allows the sender to
166  // transmit three segments initially in the common case when using 1500
167  // byte packets.
168  //
169  // Equivalently, the upper bound for the initial window size is based on
170  // the MSS, as follows:
171  //
172  // If (MSS <= 1095 bytes)
173  // then win <= 4 * MSS;
174  // If (1095 bytes < MSS < 2190 bytes)
175  // then win <= 4380;
176  // If (2190 bytes <= MSS)
177  // then win <= 2 * MSS;
178  //
179  // This increased initial window is optional: a TCP MAY start with a
180  // larger initial window. However, we expect that most general-purpose
181  // TCP implementations would choose to use the larger initial congestion
182  // window given in equation (1) above.
183  //
184  // This upper bound for the initial window size represents a change from
185  // RFC 2581 [RFC2581], which specified that the congestion window be
186  // initialized to one or two segments.
187  // (...)
188  // If the SYN or SYN/ACK is
189  // lost, the initial window used by a sender after a correctly
190  // transmitted SYN MUST be one segment consisting of MSS bytes."
193  EV_DETAIL << "Enabled Increased Initial Window, CWND is set to " << state->snd_cwnd << "\n";
194  }
195  // RFC 2001, page 3:
196  // " 1. Initialization for a given connection sets cwnd to one segment
197  // and ssthresh to 65535 bytes."
198  else
199  state->snd_cwnd = state->snd_mss; // RFC 2001
200 
201  if (active) {
202  // finish connection setup with ACK (possibly piggybacked on data)
203  EV_INFO << "Completing connection setup by sending ACK (possibly piggybacked on data)\n";
204  if (!sendData(false)) // FIXME TODO - This condition is never true because the buffer is empty (at this time) therefore the first ACK is never piggyback on data
205  conn->sendAck();
206  }
207 }
virtual void sendAck()
Utility: send ACK.
Definition: TCPConnectionUtil.cc:543
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
TCPBaseAlgStateVariables *& state
Definition: TCPBaseAlg.h:108
bool increased_IW_enabled
Definition: TCPConnection.h:201
uint32 snd_mss
Definition: TCPConnection.h:159
uint32_t uint32
Definition: Compat.h:30
int syn_rexmit_count
Definition: TCPConnection.h:182
TCPConnection * conn
Definition: TCPAlgorithm.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::TCPBaseAlg::initialize ( )
overridevirtual

Create timers, etc.

Reimplemented from inet::tcp::TCPAlgorithm.

Reimplemented in inet::tcp::TCPNoCongestionControl.

Referenced by inet::tcp::TCPNoCongestionControl::initialize().

130 {
132 
133  rexmitTimer = new cMessage("REXMIT");
134  persistTimer = new cMessage("PERSIST");
135  delayedAckTimer = new cMessage("DELAYEDACK");
136  keepAliveTimer = new cMessage("KEEPALIVE");
137 
138  rexmitTimer->setContextPointer(conn);
139  persistTimer->setContextPointer(conn);
140  delayedAckTimer->setContextPointer(conn);
141  keepAliveTimer->setContextPointer(conn);
142 
143  if (conn->getTcpMain()->recordStatistics) {
144  cwndVector = new cOutVector("cwnd");
145  ssthreshVector = new cOutVector("ssthresh");
146  rttVector = new cOutVector("measured RTT");
147  srttVector = new cOutVector("smoothed RTT");
148  rttvarVector = new cOutVector("RTTVAR");
149  rtoVector = new cOutVector("RTO");
150  numRtosVector = new cOutVector("numRTOs");
151  }
152 }
cOutVector * rttvarVector
Definition: TCPBaseAlg.h:119
virtual void initialize()
Should be redefined to initialize the object: create timers, etc.
Definition: TCPAlgorithm.h:84
cOutVector * srttVector
Definition: TCPBaseAlg.h:118
cOutVector * cwndVector
Definition: TCPBaseAlg.h:115
cOutVector * rttVector
Definition: TCPBaseAlg.h:117
TCP * getTcpMain()
Definition: TCPConnection.h:609
bool recordStatistics
Definition: TCP.h:158
cMessage * rexmitTimer
Definition: TCPBaseAlg.h:110
cMessage * delayedAckTimer
Definition: TCPBaseAlg.h:112
cMessage * persistTimer
Definition: TCPBaseAlg.h:111
cOutVector * ssthreshVector
Definition: TCPBaseAlg.h:116
cOutVector * rtoVector
Definition: TCPBaseAlg.h:120
TCPConnection * conn
Definition: TCPAlgorithm.h:40
cOutVector * numRtosVector
Definition: TCPBaseAlg.h:121
cMessage * keepAliveTimer
Definition: TCPBaseAlg.h:113
void inet::tcp::TCPBaseAlg::processDelayedAckTimer ( TCPEventCode event)
protectedvirtual

Referenced by processTimer().

338 {
339  state->ack_now = true;
340  conn->sendAck();
341 }
virtual void sendAck()
Utility: send ACK.
Definition: TCPConnectionUtil.cc:543
TCPBaseAlgStateVariables *& state
Definition: TCPBaseAlg.h:108
bool ack_now
Definition: TCPConnection.h:204
TCPConnection * conn
Definition: TCPAlgorithm.h:40
void inet::tcp::TCPBaseAlg::processKeepAliveTimer ( TCPEventCode event)
protectedvirtual

Referenced by processTimer().

344 {
345  // TBD
346  // RFC 1122, page 102:
347  // "A "keep-alive" mechanism periodically probes the other
348  // end of a connection when the connection is otherwise
349  // idle, even when there is no data to be sent. The TCP
350  // specification does not include a keep-alive mechanism
351  // because it could: (1) cause perfectly good connections
352  // to break during transient Internet failures; (2)
353  // consume unnecessary bandwidth ("if no one is using the
354  // connection, who cares if it is still good?"); and (3)
355  // cost money for an Internet path that charges for
356  // packets."
357 }
void inet::tcp::TCPBaseAlg::processPersistTimer ( TCPEventCode event)
protectedvirtual

Referenced by processTimer().

310 {
311  // setup and restart the PERSIST timer
312  // FIXME Calculation of PERSIST timer is not as simple as done here!
313  // It depends on RTT calculations and is bounded to 5-60 seconds.
314  // This simplified PERSIST timer calculation generates values
315  // as presented in [Stevens, W.R.: TCP/IP Illustrated, Volume 1, chapter 22.2]
316  // (5, 5, 6, 12, 24, 48, 60, 60, 60...)
317  if (state->persist_factor == 0)
319  else if (state->persist_factor < 64)
321 
322  state->persist_timeout = state->persist_factor * 1.5; // 1.5 is a factor for typical LAN connection [Stevens, W.R.: TCP/IP Ill. Vol. 1, chapter 22.2]
323 
324  // PERSIST timer is bounded to 5-60 seconds
327 
330 
332 
333  // sending persist probe
334  conn->sendProbe();
335 }
simtime_t persist_timeout
current persist timeout
Definition: TCPBaseAlg.h:49
TCPBaseAlgStateVariables *& state
Definition: TCPBaseAlg.h:108
virtual bool sendProbe()
Utility: sends 1 bytes as "probe", called by the "persist" mechanism.
Definition: TCPConnectionUtil.cc:771
simtime_t rexmit_timeout
current retransmission timeout (aka RTO)
Definition: TCPBaseAlg.h:43
uint persist_factor
persist factor
Definition: TCPBaseAlg.h:48
cMessage * persistTimer
Definition: TCPBaseAlg.h:111
#define MIN_PERSIST_TIMEOUT
Definition: TCPBaseAlg.cc:48
#define MAX_PERSIST_TIMEOUT
Definition: TCPBaseAlg.cc:49
void scheduleTimeout(cMessage *msg, simtime_t timeout)
Utility: start a timer.
Definition: TCPConnection.h:524
TCPConnection * conn
Definition: TCPAlgorithm.h:40
void inet::tcp::TCPBaseAlg::processRexmitTimer ( TCPEventCode event)
protectedvirtual

Reimplemented in inet::tcp::TCPVegas, inet::tcp::TCPWestwood, inet::tcp::TCPTahoe, inet::tcp::TCPNewReno, inet::tcp::TCPReno, and inet::tcp::TCPNoCongestionControl.

Referenced by inet::tcp::TCPNoCongestionControl::processRexmitTimer(), inet::tcp::TCPReno::processRexmitTimer(), inet::tcp::TCPNewReno::processRexmitTimer(), inet::tcp::TCPTahoe::processRexmitTimer(), inet::tcp::TCPWestwood::processRexmitTimer(), inet::tcp::TCPVegas::processRexmitTimer(), and processTimer().

232 {
233  EV_DETAIL << "TCB: " << state->info() << "\n";
234 
235  //"
236  // For any state if the retransmission timeout expires on a segment in
237  // the retransmission queue, send the segment at the front of the
238  // retransmission queue again, reinitialize the retransmission timer,
239  // and return.
240  //"
241  // Also: abort connection after max 12 retries.
242  //
243  // However, retransmission is actually more complicated than that
244  // in RFC 793 above, we'll leave it to subclasses (e.g. TCPTahoe, TCPReno).
245  //
247  EV_DETAIL << "Retransmission count exceeds " << MAX_REXMIT_COUNT << ", aborting connection\n";
249  event = TCP_E_ABORT; // TBD maybe rather introduce a TCP_E_TIMEDOUT event
250  return;
251  }
252 
253  EV_INFO << "Performing retransmission #" << state->rexmit_count
254  << "; increasing RTO from " << state->rexmit_timeout << "s ";
255 
256  //
257  // Karn's algorithm is implemented below:
258  // (1) don't measure RTT for retransmitted packets.
259  // (2) RTO should be doubled after retransmission ("exponential back-off")
260  //
261 
262  // restart the retransmission timer with twice the latest RTO value, or with the max, whichever is smaller
266 
268 
269  EV_INFO << " to " << state->rexmit_timeout << "s, and cancelling RTT measurement\n";
270 
271  // cancel round-trip time measurement
272  state->rtseq_sendtime = 0;
273 
274  state->numRtos++;
275 
276  if (numRtosVector)
277  numRtosVector->record(state->numRtos);
278 
279  // if sacked_enabled reset sack related flags
280  if (state->sack_enabled) {
283 
284  // RFC 3517, page 8: "If an RTO occurs during loss recovery as specified in this document,
285  // RecoveryPoint MUST be set to HighData. Further, the new value of
286  // RecoveryPoint MUST be preserved and the loss recovery algorithm
287  // outlined in this document MUST be terminated. In addition, a new
288  // recovery phase (as described in section 5) MUST NOT be initiated
289  // until HighACK is greater than or equal to the new value of
290  // RecoveryPoint."
291  if (state->lossRecovery) {
292  state->recoveryPoint = state->snd_max; // HighData = snd_max
293  EV_DETAIL << "Loss Recovery terminated.\n";
294  state->lossRecovery = false;
295  }
296  }
297 
298  state->time_last_data_sent = simTime();
299 
300  //
301  // Leave congestion window management and actual retransmission to
302  // subclasses (e.g. TCPTahoe, TCPReno).
303  //
304  // That is, subclasses will redefine this method, call us, then perform
305  // window adjustments and do the retransmission as they like.
306  //
307 }
virtual void resetRexmittedBit()
Called when REXMIT timer expired.
Definition: TCPSACKRexmitQueue.cc:307
virtual std::string info() const override
Definition: TCPBaseAlg.cc:78
#define MAX_REXMIT_COUNT
Definition: TCPBaseAlg.cc:44
virtual void resetSackedBit()
Called when REXMIT timer expired.
Definition: TCPSACKRexmitQueue.cc:301
uint32 recoveryPoint
Definition: TCPConnection.h:245
TCPSACKRexmitQueue * rexmitQueue
Definition: TCPConnection.h:344
TCPBaseAlgStateVariables *& state
Definition: TCPBaseAlg.h:108
virtual void signalConnectionTimeout()
Utility: signal to user that connection timed out.
Definition: TCPConnectionUtil.cc:288
cMessage * rexmitTimer
Definition: TCPBaseAlg.h:110
#define MAX_REXMIT_TIMEOUT
Definition: TCPBaseAlg.cc:47
Definition: TCPConnection.h:90
simtime_t rexmit_timeout
current retransmission timeout (aka RTO)
Definition: TCPBaseAlg.h:43
bool sack_enabled
Definition: TCPConnection.h:235
simtime_t rtseq_sendtime
time when rtseq was sent (0 if RTT measurement is not running)
Definition: TCPBaseAlg.h:60
uint32 numRtos
number of RTOs
Definition: TCPBaseAlg.h:71
int rexmit_count
retransmit count
Definition: TCPBaseAlg.h:42
simtime_t time_last_data_sent
Definition: TCPConnection.h:231
void scheduleTimeout(cMessage *msg, simtime_t timeout)
Utility: start a timer.
Definition: TCPConnection.h:524
bool lossRecovery
Definition: TCPConnection.h:248
TCPConnection * conn
Definition: TCPAlgorithm.h:40
cOutVector * numRtosVector
Definition: TCPBaseAlg.h:121
uint32 snd_max
Definition: TCPConnection.h:166
void inet::tcp::TCPBaseAlg::processTimer ( cMessage *  timer,
TCPEventCode event 
)
overridevirtual

Process REXMIT, PERSIST, DELAYED-ACK and KEEP-ALIVE timers.

Implements inet::tcp::TCPAlgorithm.

218 {
219  if (timer == rexmitTimer)
220  processRexmitTimer(event);
221  else if (timer == persistTimer)
222  processPersistTimer(event);
223  else if (timer == delayedAckTimer)
224  processDelayedAckTimer(event);
225  else if (timer == keepAliveTimer)
226  processKeepAliveTimer(event);
227  else
228  throw cRuntimeError(timer, "unrecognized timer");
229 }
virtual void processRexmitTimer(TCPEventCode &event)
Definition: TCPBaseAlg.cc:231
virtual void processDelayedAckTimer(TCPEventCode &event)
Definition: TCPBaseAlg.cc:337
cMessage * rexmitTimer
Definition: TCPBaseAlg.h:110
virtual void processPersistTimer(TCPEventCode &event)
Definition: TCPBaseAlg.cc:309
cMessage * delayedAckTimer
Definition: TCPBaseAlg.h:112
cMessage * persistTimer
Definition: TCPBaseAlg.h:111
virtual void processKeepAliveTimer(TCPEventCode &event)
Definition: TCPBaseAlg.cc:343
cMessage * keepAliveTimer
Definition: TCPBaseAlg.h:113
void inet::tcp::TCPBaseAlg::receivedAckForDataNotYetSent ( uint32  seq)
overridevirtual

Called after we received an ACK for data not yet sent.

According to RFC 793 this function should send an ACK.

Implements inet::tcp::TCPAlgorithm.

629 {
630  // Note: In this case no immediate ACK will be send because not mentioned
631  // in [Stevens, W.R.: TCP/IP Illustrated, Volume 2, page 861].
632  // To force immediate ACK use:
633  // state->ack_now = true;
634  // tcpEV << "ACK acks something not yet sent, sending immediate ACK\n";
635  EV_INFO << "ACK acks something not yet sent, sending ACK\n";
636  conn->sendAck();
637 }
virtual void sendAck()
Utility: send ACK.
Definition: TCPConnectionUtil.cc:543
TCPConnection * conn
Definition: TCPAlgorithm.h:40
void inet::tcp::TCPBaseAlg::receivedDataAck ( uint32  firstSeqAcked)
overridevirtual

Called after we received an ACK which acked some data (that is, we could advance snd_una).

At this point the state variables (snd_una, snd_wnd) have already been updated. The argument firstSeqAcked is the previous snd_una value, that is, the number of bytes acked is (snd_una - firstSeqAcked). The dupack counter still reflects the old value (needed for Reno and NewReno); it'll be reset to 0 after this call returns.

Implements inet::tcp::TCPAlgorithm.

Reimplemented in inet::tcp::TCPVegas, inet::tcp::TCPWestwood, inet::tcp::TCPNoCongestionControl, inet::tcp::TCPTahoe, inet::tcp::TCPNewReno, and inet::tcp::TCPReno.

Referenced by inet::tcp::TCPNewReno::receivedDataAck(), inet::tcp::TCPReno::receivedDataAck(), inet::tcp::TCPNoCongestionControl::receivedDataAck(), inet::tcp::TCPTahoe::receivedDataAck(), inet::tcp::TCPWestwood::receivedDataAck(), and inet::tcp::TCPVegas::receivedDataAck().

530 {
531  if (!state->ts_enabled) {
532  // if round-trip time measurement is running, check if rtseq has been acked
533  if (state->rtseq_sendtime != 0 && seqLess(state->rtseq, state->snd_una)) {
534  // print value
535  EV_DETAIL << "Round-trip time measured on rtseq=" << state->rtseq << ": "
536  << floor((simTime() - state->rtseq_sendtime) * 1000 + 0.5) << "ms\n";
537 
538  rttMeasurementComplete(state->rtseq_sendtime, simTime()); // update RTT variables with new value
539 
540  // measurement finished
541  state->rtseq_sendtime = 0;
542  }
543  }
544 
545  //
546  // handling of retransmission timer: if the ACK is for the last segment sent
547  // (no data in flight), cancel the timer, otherwise restart the timer
548  // with the current RTO value.
549  //
550  if (state->snd_una == state->snd_max) {
551  if (rexmitTimer->isScheduled()) {
552  EV_INFO << "ACK acks all outstanding segments, cancel REXMIT timer\n";
554  }
555  else
556  EV_INFO << "There were no outstanding segments, nothing new in this ACK.\n";
557  }
558  else {
559  EV_INFO << "ACK acks some but not all outstanding segments ("
560  << (state->snd_max - state->snd_una) << " bytes outstanding), "
561  << "restarting REXMIT timer\n";
564  }
565 
566  //
567  // handling of PERSIST timer:
568  // If data sender received a zero-sized window, check retransmission timer.
569  // If retransmission timer is not scheduled, start PERSIST timer if not already
570  // running.
571  //
572  // If data sender received a non zero-sized window, check PERSIST timer.
573  // If PERSIST timer is scheduled, cancel PERSIST timer.
574  //
575  if (state->snd_wnd == 0) { // received zero-sized window?
576  if (rexmitTimer->isScheduled()) {
577  if (persistTimer->isScheduled()) {
578  EV_INFO << "Received zero-sized window and REXMIT timer is running therefore PERSIST timer is canceled.\n";
580  state->persist_factor = 0;
581  }
582  else
583  EV_INFO << "Received zero-sized window and REXMIT timer is running therefore PERSIST timer is not started.\n";
584  }
585  else {
586  if (!persistTimer->isScheduled()) {
587  EV_INFO << "Received zero-sized window therefore PERSIST timer is started.\n";
589  }
590  else
591  EV_INFO << "Received zero-sized window and PERSIST timer is already running.\n";
592  }
593  }
594  else { // received non zero-sized window?
595  if (persistTimer->isScheduled()) {
596  EV_INFO << "Received non zero-sized window therefore PERSIST timer is canceled.\n";
598  state->persist_factor = 0;
599  }
600  }
601 
602  //
603  // Leave congestion window management and possible sending data to
604  // subclasses (e.g. TCPTahoe, TCPReno).
605  //
606  // That is, subclasses will redefine this method, call us, then perform
607  // window adjustments and send data (if there's room in the window).
608  //
609 }
bool ts_enabled
Definition: TCPConnection.h:226
simtime_t persist_timeout
current persist timeout
Definition: TCPBaseAlg.h:49
bool seqLess(uint32 a, uint32 b)
Definition: TCPSegment.h:32
TCPBaseAlgStateVariables *& state
Definition: TCPBaseAlg.h:108
uint32 rtseq
round-trip time measurements
Definition: TCPBaseAlg.h:59
cMessage * rexmitTimer
Definition: TCPBaseAlg.h:110
uint32 snd_wnd
Definition: TCPConnection.h:167
virtual void startRexmitTimer()
Start REXMIT timer and initialize retransmission variables.
Definition: TCPBaseAlg.cc:359
simtime_t rtseq_sendtime
time when rtseq was sent (0 if RTT measurement is not running)
Definition: TCPBaseAlg.h:60
uint persist_factor
persist factor
Definition: TCPBaseAlg.h:48
uint32 snd_una
Definition: TCPConnection.h:164
cMessage * persistTimer
Definition: TCPBaseAlg.h:111
void scheduleTimeout(cMessage *msg, simtime_t timeout)
Utility: start a timer.
Definition: TCPConnection.h:524
virtual void rttMeasurementComplete(simtime_t tSent, simtime_t tAcked)
Update state vars with new measured RTT value.
Definition: TCPBaseAlg.cc:369
TCPConnection * conn
Definition: TCPAlgorithm.h:40
uint32 snd_max
Definition: TCPConnection.h:166
cMessage * cancelEvent(cMessage *msg)
Utility function.
Definition: TCPBaseAlg.h:156
void inet::tcp::TCPBaseAlg::receivedDuplicateAck ( )
overridevirtual

Called after we received a duplicate ACK (that is: ackNo == snd_una, no data in segment, segment doesn't carry window update, and also, we have unacked data).

The dupack counter got already updated when calling this method (i.e. dupacks == 1 on first duplicate ACK.)

Implements inet::tcp::TCPAlgorithm.

Reimplemented in inet::tcp::TCPVegas, inet::tcp::TCPWestwood, inet::tcp::TCPTahoe, inet::tcp::TCPNewReno, and inet::tcp::TCPReno.

Referenced by inet::tcp::TCPNewReno::receivedDuplicateAck(), inet::tcp::TCPReno::receivedDuplicateAck(), inet::tcp::TCPTahoe::receivedDuplicateAck(), inet::tcp::TCPWestwood::receivedDuplicateAck(), and inet::tcp::TCPVegas::receivedDuplicateAck().

612 {
613  EV_INFO << "Duplicate ACK #" << state->dupacks << "\n";
614 
615  bool fullSegmentsOnly = state->nagle_enabled && state->snd_una != state->snd_max;
616  if (state->dupacks < DUPTHRESH && state->limited_transmit_enabled) // DUPTRESH = 3
617  conn->sendOneNewSegment(fullSegmentsOnly, state->snd_cwnd); // RFC 3042
618 
619  //
620  // Leave to subclasses (e.g. TCPTahoe, TCPReno) whatever they want to do
621  // on duplicate Acks.
622  //
623  // That is, subclasses will redefine this method, call us, then perform
624  // whatever action they want to do on dupAcks (e.g. retransmitting one segment).
625  //
626 }
bool nagle_enabled
Definition: TCPConnection.h:198
TCPBaseAlgStateVariables *& state
Definition: TCPBaseAlg.h:108
virtual void sendOneNewSegment(bool fullSegmentsOnly, uint32 congestionWindow)
Utility: send one new segment from snd_max if allowed (RFC 3042).
Definition: TCPConnectionUtil.cc:1337
uint32 dupacks
Definition: TCPConnection.h:255
#define DUPTHRESH
Definition: TCPConnection.h:126
uint32 snd_una
Definition: TCPConnection.h:164
TCPConnection * conn
Definition: TCPAlgorithm.h:40
uint32 snd_max
Definition: TCPConnection.h:166
uint32 snd_cwnd
congestion window
Definition: TCPBaseAlg.h:54
bool limited_transmit_enabled
Definition: TCPConnection.h:200
void inet::tcp::TCPBaseAlg::receivedOutOfOrderSegment ( )
overridevirtual

Called after receiving data which are in the window, but not at its left edge (seq != rcv_nxt).

This indicates that either segments got re-ordered in the way, or one segment was lost. RFC 1122 and RFC 2001 recommend sending an immediate ACK here (Fast Retransmit relies on that).

Implements inet::tcp::TCPAlgorithm.

484 {
485  state->ack_now = true;
486  EV_INFO << "Out-of-order segment, sending immediate ACK\n";
487  conn->sendAck();
488 }
virtual void sendAck()
Utility: send ACK.
Definition: TCPConnectionUtil.cc:543
TCPBaseAlgStateVariables *& state
Definition: TCPBaseAlg.h:108
bool ack_now
Definition: TCPConnection.h:204
TCPConnection * conn
Definition: TCPAlgorithm.h:40
void inet::tcp::TCPBaseAlg::receiveSeqChanged ( )
overridevirtual

Called after rcv_nxt got advanced, either because we received in-sequence data ("text" in RFC 793 lingo) or a FIN.

At this point, rcv_nxt has already been updated. This method should take care to send or schedule an ACK some time.

Implements inet::tcp::TCPAlgorithm.

491 {
492  // If we send a data segment already (with the updated seqNo) there is no need to send an additional ACK
493  if (state->full_sized_segment_counter == 0 && !state->ack_now && state->last_ack_sent == state->rcv_nxt && !delayedAckTimer->isScheduled()) { // ackSent?
494  // tcpEV << "ACK has already been sent (possibly piggybacked on data)\n";
495  }
496  else {
497  // RFC 2581, page 6:
498  // "3.2 Fast Retransmit/Fast Recovery
499  // (...)
500  // In addition, a TCP receiver SHOULD send an immediate ACK
501  // when the incoming segment fills in all or part of a gap in the
502  // sequence space."
503  if (state->lossRecovery)
504  state->ack_now = true; // although not mentioned in [Stevens, W.R.: TCP/IP Illustrated, Volume 2, page 861] seems like we have to set ack_now
505 
506  if (!state->delayed_acks_enabled) { // delayed ACK disabled
507  EV_INFO << "rcv_nxt changed to " << state->rcv_nxt << ", (delayed ACK disabled) sending ACK now\n";
508  conn->sendAck();
509  }
510  else { // delayed ACK enabled
511  if (state->ack_now) {
512  EV_INFO << "rcv_nxt changed to " << state->rcv_nxt << ", (delayed ACK enabled, but ack_now is set) sending ACK now\n";
513  conn->sendAck();
514  }
515  // RFC 1122, page 96: "in a stream of full-sized segments there SHOULD be an ACK for at least every second segment."
516  else if (state->full_sized_segment_counter >= 2) {
517  EV_INFO << "rcv_nxt changed to " << state->rcv_nxt << ", (delayed ACK enabled, but full_sized_segment_counter=" << state->full_sized_segment_counter << ") sending ACK now\n";
518  conn->sendAck();
519  }
520  else {
521  EV_INFO << "rcv_nxt changed to " << state->rcv_nxt << ", (delayed ACK enabled and full_sized_segment_counter=" << state->full_sized_segment_counter << ") scheduling ACK\n";
522  if (!delayedAckTimer->isScheduled()) // schedule delayed ACK timer if not already running
524  }
525  }
526  }
527 }
virtual void sendAck()
Utility: send ACK.
Definition: TCPConnectionUtil.cc:543
uint32 full_sized_segment_counter
Definition: TCPConnection.h:203
uint32 last_ack_sent
Definition: TCPConnection.h:230
uint32 rcv_nxt
Definition: TCPConnection.h:174
TCPBaseAlgStateVariables *& state
Definition: TCPBaseAlg.h:108
cMessage * delayedAckTimer
Definition: TCPBaseAlg.h:112
#define DELAYED_ACK_TIMEOUT
Definition: TCPBaseAlg.cc:43
bool ack_now
Definition: TCPConnection.h:204
bool delayed_acks_enabled
Definition: TCPConnection.h:199
void scheduleTimeout(cMessage *msg, simtime_t timeout)
Utility: start a timer.
Definition: TCPConnection.h:524
TCPConnection * conn
Definition: TCPAlgorithm.h:40
bool lossRecovery
Definition: TCPConnection.h:248
void inet::tcp::TCPBaseAlg::restartRexmitTimer ( )
overridevirtual

Restart REXMIT timer.

Implements inet::tcp::TCPAlgorithm.

Referenced by inet::tcp::TCPNewReno::receivedDataAck(), inet::tcp::TCPReno::receivedDuplicateAck(), inet::tcp::TCPWestwood::receivedDuplicateAck(), and inet::tcp::TCPVegas::receivedDuplicateAck().

675 {
676  if (rexmitTimer->isScheduled())
678 
680 }
cMessage * rexmitTimer
Definition: TCPBaseAlg.h:110
virtual void startRexmitTimer()
Start REXMIT timer and initialize retransmission variables.
Definition: TCPBaseAlg.cc:359
cMessage * cancelEvent(cMessage *msg)
Utility function.
Definition: TCPBaseAlg.h:156
void inet::tcp::TCPBaseAlg::rttMeasurementComplete ( simtime_t  tSent,
simtime_t  tAcked 
)
protectedvirtual

Update state vars with new measured RTT value.

Passing two simtime_t's will allow rttMeasurementComplete() to do calculations in double or in 200ms/500ms ticks, as needed)

Referenced by receivedDataAck(), and rttMeasurementCompleteUsingTS().

370 {
371  //
372  // Jacobson's algorithm for estimating RTT and adaptively setting RTO.
373  //
374  // Note: this implementation calculates in doubles. An impl. which uses
375  // 500ms ticks is available from old tcpmodule.cc:calcRetransTimer().
376  //
377 
378  // update smoothed RTT estimate (srtt) and variance (rttvar)
379  const double g = 0.125; // 1 / 8; (1 - alpha) where alpha == 7 / 8;
380  simtime_t newRTT = tAcked - tSent;
381 
382  simtime_t& srtt = state->srtt;
383  simtime_t& rttvar = state->rttvar;
384 
385  simtime_t err = newRTT - srtt;
386 
387  srtt += g * err;
388  rttvar += g * (fabs(err) - rttvar);
389 
390  // assign RTO (here: rexmit_timeout) a new value
391  simtime_t rto = srtt + 4 * rttvar;
392 
393  if (rto > MAX_REXMIT_TIMEOUT)
394  rto = MAX_REXMIT_TIMEOUT;
395  else if (rto < MIN_REXMIT_TIMEOUT)
396  rto = MIN_REXMIT_TIMEOUT;
397 
398  state->rexmit_timeout = rto;
399 
400  // record statistics
401  EV_DETAIL << "Measured RTT=" << (newRTT * 1000) << "ms, updated SRTT=" << (srtt * 1000)
402  << "ms, new RTO=" << (rto * 1000) << "ms\n";
403 
404  if (rttVector)
405  rttVector->record(newRTT);
406 
407  if (srttVector)
408  srttVector->record(srtt);
409 
410  if (rttvarVector)
411  rttvarVector->record(rttvar);
412 
413  if (rtoVector)
414  rtoVector->record(rto);
415 }
cOutVector * rttvarVector
Definition: TCPBaseAlg.h:119
cOutVector * srttVector
Definition: TCPBaseAlg.h:118
cOutVector * rttVector
Definition: TCPBaseAlg.h:117
simtime_t srtt
round-trip time estimation (Jacobson&#39;s algorithm)
Definition: TCPBaseAlg.h:65
TCPBaseAlgStateVariables *& state
Definition: TCPBaseAlg.h:108
#define MAX_REXMIT_TIMEOUT
Definition: TCPBaseAlg.cc:47
simtime_t rexmit_timeout
current retransmission timeout (aka RTO)
Definition: TCPBaseAlg.h:43
#define MIN_REXMIT_TIMEOUT
Definition: TCPBaseAlg.cc:45
simtime_t rttvar
variance of round-trip time
Definition: TCPBaseAlg.h:66
cOutVector * rtoVector
Definition: TCPBaseAlg.h:120
milli< kg >::type g
Definition: Units.h:900
void inet::tcp::TCPBaseAlg::rttMeasurementCompleteUsingTS ( uint32  echoedTS)
overrideprotectedvirtual

Converting uint32 echoedTS to simtime_t and calling rttMeasurementComplete() to update state vars with new measured RTT value.

Implements inet::tcp::TCPAlgorithm.

418 {
419  ASSERT(state->ts_enabled);
420 
421  // Note: The TS option is using uint32 values (ms precision) therefore we convert the current simTime also to a uint32 value (ms precision)
422  // and then convert back to simtime_t to use rttMeasurementComplete() to update srtt and rttvar
423  uint32 now = conn->convertSimtimeToTS(simTime());
424  simtime_t tSent = conn->convertTSToSimtime(echoedTS);
425  simtime_t tAcked = conn->convertTSToSimtime(now);
426  rttMeasurementComplete(tSent, tAcked);
427 }
bool ts_enabled
Definition: TCPConnection.h:226
static uint32 convertSimtimeToTS(simtime_t simtime)
Utility: converts a given simtime to a timestamp (TS).
Definition: TCPConnectionUtil.cc:1414
TCPBaseAlgStateVariables *& state
Definition: TCPBaseAlg.h:108
uint32_t uint32
Definition: Compat.h:30
static simtime_t convertTSToSimtime(uint32 timestamp)
Utility: converts a given timestamp (TS) to a simtime.
Definition: TCPConnectionUtil.cc:1422
virtual void rttMeasurementComplete(simtime_t tSent, simtime_t tAcked)
Update state vars with new measured RTT value.
Definition: TCPBaseAlg.cc:369
TCPConnection * conn
Definition: TCPAlgorithm.h:40
void inet::tcp::TCPBaseAlg::segmentRetransmitted ( uint32  fromseq,
uint32  toseq 
)
overridevirtual

Called after we retransmitted segment.

The argument fromseq is the seqno of the first byte sent. The argument toseq is the seqno of the last byte sent+1.

Implements inet::tcp::TCPAlgorithm.

Reimplemented in inet::tcp::TCPVegas, and inet::tcp::TCPWestwood.

Referenced by inet::tcp::TCPWestwood::segmentRetransmitted(), and inet::tcp::TCPVegas::segmentRetransmitted().

671 {
672 }
void inet::tcp::TCPBaseAlg::sendCommandInvoked ( )
overridevirtual

Called after user sent TCP_C_SEND command to us.

Implements inet::tcp::TCPAlgorithm.

478 {
479  // try sending
480  sendData(true);
481 }
virtual bool sendData(bool sendCommandInvoked)
Send data, observing Nagle&#39;s algorithm and congestion window.
Definition: TCPBaseAlg.cc:429
bool inet::tcp::TCPBaseAlg::sendData ( bool  sendCommandInvoked)
protectedvirtual

Send data, observing Nagle's algorithm and congestion window.

Referenced by established(), inet::tcp::TCPNewReno::receivedDataAck(), inet::tcp::TCPReno::receivedDataAck(), inet::tcp::TCPNoCongestionControl::receivedDataAck(), inet::tcp::TCPTahoe::receivedDataAck(), inet::tcp::TCPWestwood::receivedDataAck(), inet::tcp::TCPVegas::receivedDataAck(), inet::tcp::TCPReno::receivedDuplicateAck(), inet::tcp::TCPNewReno::receivedDuplicateAck(), inet::tcp::TCPWestwood::receivedDuplicateAck(), inet::tcp::TCPVegas::receivedDuplicateAck(), and sendCommandInvoked().

430 {
431  //
432  // Nagle's algorithm: when a TCP connection has outstanding data that has not
433  // yet been acknowledged, small segments cannot be sent until the outstanding
434  // data is acknowledged. (In this case, small amounts of data are collected
435  // by TCP and sent in a single segment.)
436  //
437  // FIXME there's also something like this: can still send if
438  // "b) a segment that can be sent is at least half the size of
439  // the largest window ever advertised by the receiver"
440 
441  bool fullSegmentsOnly = sendCommandInvoked && state->nagle_enabled && state->snd_una != state->snd_max;
442 
443  if (fullSegmentsOnly)
444  EV_INFO << "Nagle is enabled and there's unacked data: only full segments will be sent\n";
445 
446  // RFC 2581, pages 7 and 8: "When TCP has not received a segment for
447  // more than one retransmission timeout, cwnd is reduced to the value
448  // of the restart window (RW) before transmission begins.
449  // For the purposes of this standard, we define RW = IW.
450  // (...)
451  // Using the last time a segment was received to determine whether or
452  // not to decrease cwnd fails to deflate cwnd in the common case of
453  // persistent HTTP connections [HTH98].
454  // (...)
455  // Therefore, a TCP SHOULD set cwnd to no more than RW before beginning
456  // transmission if the TCP has not sent data in an interval exceeding
457  // the retransmission timeout."
458  if (!conn->isSendQueueEmpty()) { // do we have any data to send?
459  if ((simTime() - state->time_last_data_sent) > state->rexmit_timeout) {
460  // RFC 5681, page 11: "For the purposes of this standard, we define RW = min(IW,cwnd)."
463  else
465 
466  EV_INFO << "Restarting idle connection, CWND is set to " << state->snd_cwnd << "\n";
467  }
468  }
469 
470  //
471  // Send window is effectively the minimum of the congestion window (cwnd)
472  // and the advertised window (snd_wnd).
473  //
474  return conn->sendData(fullSegmentsOnly, state->snd_cwnd);
475 }
double min(const double a, const double b)
Returns the minimum of a and b.
Definition: SCTPAssociation.h:270
bool nagle_enabled
Definition: TCPConnection.h:198
virtual bool isSendQueueEmpty()
Utility: checks if send queue is empty (no data to send).
Definition: TCPConnectionUtil.cc:1430
double max(double a, double b)
Returns the greater of the given parameters.
Definition: INETMath.h:161
virtual void sendCommandInvoked() override
Called after user sent TCP_C_SEND command to us.
Definition: TCPBaseAlg.cc:477
TCPBaseAlgStateVariables *& state
Definition: TCPBaseAlg.h:108
bool increased_IW_enabled
Definition: TCPConnection.h:201
uint32 snd_mss
Definition: TCPConnection.h:159
simtime_t rexmit_timeout
current retransmission timeout (aka RTO)
Definition: TCPBaseAlg.h:43
uint32 snd_una
Definition: TCPConnection.h:164
uint32_t uint32
Definition: Compat.h:30
simtime_t time_last_data_sent
Definition: TCPConnection.h:231
virtual bool sendData(bool fullSegmentsOnly, uint32 congestionWindow)
Utility: Send data from sendQueue, at most congestionWindow.
Definition: TCPConnectionUtil.cc:662
TCPConnection * conn
Definition: TCPAlgorithm.h:40
uint32 snd_max
Definition: TCPConnection.h:166
uint32 snd_cwnd
congestion window
Definition: TCPBaseAlg.h:54
void inet::tcp::TCPBaseAlg::startRexmitTimer ( )
protectedvirtual

Start REXMIT timer and initialize retransmission variables.

Referenced by dataSent(), receivedDataAck(), and restartRexmitTimer().

360 {
361  // start counting retransmissions for this seq number.
362  // Note: state->rexmit_timeout is set from rttMeasurementComplete().
363  state->rexmit_count = 0;
364 
365  // schedule timer
367 }
TCPBaseAlgStateVariables *& state
Definition: TCPBaseAlg.h:108
cMessage * rexmitTimer
Definition: TCPBaseAlg.h:110
simtime_t rexmit_timeout
current retransmission timeout (aka RTO)
Definition: TCPBaseAlg.h:43
int rexmit_count
retransmit count
Definition: TCPBaseAlg.h:42
void scheduleTimeout(cMessage *msg, simtime_t timeout)
Utility: start a timer.
Definition: TCPConnection.h:524
TCPConnection * conn
Definition: TCPAlgorithm.h:40

Member Data Documentation

cMessage* inet::tcp::TCPBaseAlg::delayedAckTimer
protected
cMessage* inet::tcp::TCPBaseAlg::keepAliveTimer
protected
cOutVector* inet::tcp::TCPBaseAlg::numRtosVector
protected
cMessage* inet::tcp::TCPBaseAlg::persistTimer
protected
cOutVector* inet::tcp::TCPBaseAlg::rtoVector
protected
cOutVector* inet::tcp::TCPBaseAlg::rttvarVector
protected
cOutVector* inet::tcp::TCPBaseAlg::rttVector
protected
cOutVector* inet::tcp::TCPBaseAlg::srttVector
protected

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