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::DcTcpFamily inet::tcp::TcpNewReno inet::tcp::TcpReno inet::tcp::TcpTahoe inet::tcp::DcTcp

Protected Attributes

TcpBaseAlgStateVariables *& state
 
cMessage * rexmitTimer
 
cMessage * persistTimer
 
cMessage * delayedAckTimer
 
cMessage * keepAliveTimer
 
- Protected Attributes inherited from inet::tcp::TcpAlgorithm
TcpConnectionconn
 
TcpStateVariablesstate
 

Static Protected Attributes

static simsignal_t cwndSignal = cComponent::registerSignal("cwnd")
 
static simsignal_t ssthreshSignal = cComponent::registerSignal("ssthresh")
 
static simsignal_t rttSignal = cComponent::registerSignal("rtt")
 
static simsignal_t srttSignal = cComponent::registerSignal("srtt")
 
static simsignal_t rttvarSignal = cComponent::registerSignal("rttvar")
 
static simsignal_t rtoSignal = cComponent::registerSignal("rto")
 
static simsignal_t numRtosSignal = cComponent::registerSignal("numRtos")
 

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)
 
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_t echoedTS) override
 Converting uint32_t 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...
 
 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_t 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_t 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_t fromseq) override
 Called after we sent data. More...
 
virtual void segmentRetransmitted (uint32_t fromseq, uint32_t toseq) override
 Called after we retransmitted segment. More...
 
virtual void restartRexmitTimer () override
 Restart REXMIT timer. More...
 
virtual bool shouldMarkAck () override
 Called before sending ACK. More...
 
virtual void processEcnInEstablished () override
 Called before processing segment in established state. More...
 

Additional Inherited Members

- 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 inherited from inet::tcp::TcpAlgorithm
virtual TcpStateVariablescreateStateVariables ()=0
 Create state block (TCB) used by this TCP variant. More...
 

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

◆ TcpBaseAlg()

inet::tcp::TcpBaseAlg::TcpBaseAlg ( )

Ctor.

95  : TcpAlgorithm(),
96  state((TcpBaseAlgStateVariables *&)TcpAlgorithm::state)
97 {
99 }

◆ ~TcpBaseAlg()

inet::tcp::TcpBaseAlg::~TcpBaseAlg ( )
virtual

Virtual dtor.

102 {
103  // Note: don't delete "state" here, it'll be deleted from TcpConnection
104 
105  // cancel and delete timers
106  if (rexmitTimer)
107  delete cancelEvent(rexmitTimer);
108  if (persistTimer)
109  delete cancelEvent(persistTimer);
110  if (delayedAckTimer)
112  if (keepAliveTimer)
113  delete cancelEvent(keepAliveTimer);
114 }

Member Function Documentation

◆ ackSent()

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.

594 {
595  state->full_sized_segment_counter = 0; // reset counter
596  state->ack_now = false; // reset flag
597  state->last_ack_sent = state->rcv_nxt; // update last_ack_sent, needed for TS option
598  // if delayed ACK timer is running, cancel it
599  if (delayedAckTimer->isScheduled())
601 }

◆ cancelEvent()

cMessage* inet::tcp::TcpBaseAlg::cancelEvent ( cMessage *  msg)
inlineprotected

Utility function.

142 { return conn->cancelEvent(msg); }

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

◆ connectionClosed()

void inet::tcp::TcpBaseAlg::connectionClosed ( )
overridevirtual

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

Implements inet::tcp::TcpAlgorithm.

◆ dataSent()

void inet::tcp::TcpBaseAlg::dataSent ( uint32_t  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.

604 {
605  // if retransmission timer not running, schedule it
606  if (!rexmitTimer->isScheduled()) {
607  EV_INFO << "Starting REXMIT timer\n";
609  }
610 
611  if (!state->ts_enabled) {
612  // start round-trip time measurement (if not already running)
613  if (state->rtseq_sendtime == 0) {
614  // remember this sequence number and when it was sent
615  state->rtseq = fromseq;
616  state->rtseq_sendtime = simTime();
617  EV_DETAIL << "Starting rtt measurement on seq=" << state->rtseq << "\n";
618  }
619  }
620 
621  state->time_last_data_sent = simTime();
622 }

Referenced by inet::tcp::TcpWestwood::dataSent(), and inet::tcp::TcpVegas::dataSent().

◆ established()

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.

Reimplemented in inet::tcp::TcpNoCongestionControl.

132 {
133  // initialize cwnd (we may learn SMSS during connection setup)
134 
135  // RFC 3390, page 2: "The upper bound for the initial window is given more precisely in
136  // (1):
137  //
138  // min (4*MSS, max (2*MSS, 4380 bytes)) (1)
139  //
140  // Note: Sending a 1500 byte packet indicates a maximum segment size
141  // (MSS) of 1460 bytes (assuming no IP or TCP options). Therefore,
142  // limiting the initial window's MSS to 4380 bytes allows the sender to
143  // transmit three segments initially in the common case when using 1500
144  // byte packets.
145  //
146  // Equivalently, the upper bound for the initial window size is based on
147  // the MSS, as follows:
148  //
149  // If (MSS <= 1095 bytes)
150  // then win <= 4 * MSS;
151  // If (1095 bytes < MSS < 2190 bytes)
152  // then win <= 4380;
153  // If (2190 bytes <= MSS)
154  // then win <= 2 * MSS;
155  //
156  // This increased initial window is optional: a TCP MAY start with a
157  // larger initial window. However, we expect that most general-purpose
158  // TCP implementations would choose to use the larger initial congestion
159  // window given in equation (1) above.
160  //
161  // This upper bound for the initial window size represents a change from
162  // RFC 2581 [RFC2581], which specified that the congestion window be
163  // initialized to one or two segments.
164  // (...)
165  // If the SYN or SYN/ACK is
166  // lost, the initial window used by a sender after a correctly
167  // transmitted SYN MUST be one segment consisting of MSS bytes."
169  state->snd_cwnd = std::min(4 * state->snd_mss, std::max(2 * state->snd_mss, (uint32_t)4380));
170  EV_DETAIL << "Enabled Increased Initial Window, CWND is set to " << state->snd_cwnd << "\n";
171  }
172  // RFC 2001, page 3:
173  // " 1. Initialization for a given connection sets cwnd to one segment
174  // and ssthresh to 65535 bytes."
175  else
176  state->snd_cwnd = state->snd_mss; // RFC 2001
177 
178  if (active) {
179  // finish connection setup with ACK (possibly piggybacked on data)
180  EV_INFO << "Completing connection setup by sending ACK (possibly piggybacked on data)\n";
181  if (!sendData(false)) // FIXME - This condition is never true because the buffer is empty (at this time) therefore the first ACK is never piggyback on data
182  conn->sendAck();
183  }
184 }

◆ initialize()

void inet::tcp::TcpBaseAlg::initialize ( )
overridevirtual

Create timers, etc.

Reimplemented from inet::tcp::TcpAlgorithm.

Reimplemented in inet::tcp::TcpNoCongestionControl, inet::tcp::TcpTahoeRenoFamily, and inet::tcp::DcTcp.

117 {
119 
120  rexmitTimer = new cMessage("REXMIT");
121  persistTimer = new cMessage("PERSIST");
122  delayedAckTimer = new cMessage("DELAYEDACK");
123  keepAliveTimer = new cMessage("KEEPALIVE");
124 
125  rexmitTimer->setContextPointer(conn);
126  persistTimer->setContextPointer(conn);
127  delayedAckTimer->setContextPointer(conn);
128  keepAliveTimer->setContextPointer(conn);
129 }

Referenced by inet::tcp::TcpTahoeRenoFamily::initialize(), and inet::tcp::TcpNoCongestionControl::initialize().

◆ processDelayedAckTimer()

void inet::tcp::TcpBaseAlg::processDelayedAckTimer ( TcpEventCode event)
protectedvirtual
314 {
315  state->ack_now = true;
316  conn->sendAck();
317 }

Referenced by processTimer().

◆ processEcnInEstablished()

void inet::tcp::TcpBaseAlg::processEcnInEstablished ( )
overridevirtual

Called before processing segment in established state.

This function process ECN marks.

Implements inet::tcp::TcpAlgorithm.

Reimplemented in inet::tcp::DcTcp.

668 {
669 
670 }

◆ processKeepAliveTimer()

void inet::tcp::TcpBaseAlg::processKeepAliveTimer ( TcpEventCode event)
protectedvirtual
320 {
321  // TODO
322  // RFC 1122, page 102:
323  // "A "keep-alive" mechanism periodically probes the other
324  // end of a connection when the connection is otherwise
325  // idle, even when there is no data to be sent. The TCP
326  // specification does not include a keep-alive mechanism
327  // because it could: (1) cause perfectly good connections
328  // to break during transient Internet failures; (2)
329  // consume unnecessary bandwidth ("if no one is using the
330  // connection, who cares if it is still good?"); and (3)
331  // cost money for an Internet path that charges for
332  // packets."
333 }

Referenced by processTimer().

◆ processPersistTimer()

void inet::tcp::TcpBaseAlg::processPersistTimer ( TcpEventCode event)
protectedvirtual
286 {
287  // setup and restart the PERSIST timer
288  // FIXME Calculation of PERSIST timer is not as simple as done here!
289  // It depends on RTT calculations and is bounded to 5-60 seconds.
290  // This simplified PERSIST timer calculation generates values
291  // as presented in [Stevens, W.R.: TCP/IP Illustrated, Volume 1, chapter 22.2]
292  // (5, 5, 6, 12, 24, 48, 60, 60, 60...)
293  if (state->persist_factor == 0)
295  else if (state->persist_factor < 64)
297 
298  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]
299 
300  // PERSIST timer is bounded to 5-60 seconds
303 
306 
307  conn->scheduleAfter(state->persist_timeout, persistTimer);
308 
309  // sending persist probe
310  conn->sendProbe();
311 }

Referenced by processTimer().

◆ processRexmitTimer()

void inet::tcp::TcpBaseAlg::processRexmitTimer ( TcpEventCode event)
protectedvirtual

Reimplemented in inet::tcp::TcpVegas, inet::tcp::TcpWestwood, inet::tcp::TcpTahoe, inet::tcp::TcpReno, inet::tcp::TcpNewReno, and inet::tcp::TcpNoCongestionControl.

209 {
210  EV_DETAIL << "TCB: " << state->str() << "\n";
211 
212  //"
213  // For any state if the retransmission timeout expires on a segment in
214  // the retransmission queue, send the segment at the front of the
215  // retransmission queue again, reinitialize the retransmission timer,
216  // and return.
217  //"
218  // Also: abort connection after max 12 retries.
219  //
220  // However, retransmission is actually more complicated than that
221  // in RFC 793 above, we'll leave it to subclasses (e.g. TcpTahoe, TcpReno).
222  //
224  EV_DETAIL << "Retransmission count exceeds " << MAX_REXMIT_COUNT << ", aborting connection\n";
226  event = TCP_E_ABORT; // TODO maybe rather introduce a TCP_E_TIMEDOUT event
227  return;
228  }
229 
230  EV_INFO << "Performing retransmission #" << state->rexmit_count
231  << "; increasing RTO from " << state->rexmit_timeout << "s ";
232 
233  //
234  // Karn's algorithm is implemented below:
235  // (1) don't measure RTT for retransmitted packets.
236  // (2) RTO should be doubled after retransmission ("exponential back-off")
237  //
238 
239  // restart the retransmission timer with twice the latest RTO value, or with the max, whichever is smaller
243 
244  conn->scheduleAfter(state->rexmit_timeout, rexmitTimer);
245 
246  EV_INFO << " to " << state->rexmit_timeout << "s, and cancelling RTT measurement\n";
247 
248  // cancel round-trip time measurement
249  state->rtseq_sendtime = 0;
250 
251  state->numRtos++;
252 
253  conn->emit(numRtosSignal, state->numRtos);
254 
255  // if sacked_enabled reset sack related flags
256  if (state->sack_enabled) {
259 
260  // RFC 3517, page 8: "If an RTO occurs during loss recovery as specified in this document,
261  // RecoveryPoint MUST be set to HighData. Further, the new value of
262  // RecoveryPoint MUST be preserved and the loss recovery algorithm
263  // outlined in this document MUST be terminated. In addition, a new
264  // recovery phase (as described in section 5) MUST NOT be initiated
265  // until HighACK is greater than or equal to the new value of
266  // RecoveryPoint."
267  if (state->lossRecovery) {
268  state->recoveryPoint = state->snd_max; // HighData = snd_max
269  EV_DETAIL << "Loss Recovery terminated.\n";
270  state->lossRecovery = false;
271  }
272  }
273 
274  state->time_last_data_sent = simTime();
275 
276  //
277  // Leave congestion window management and actual retransmission to
278  // subclasses (e.g. TcpTahoe, TcpReno).
279  //
280  // That is, subclasses will redefine this method, call us, then perform
281  // window adjustments and do the retransmission as they like.
282  //
283 }

Referenced by inet::tcp::TcpNoCongestionControl::processRexmitTimer(), inet::tcp::TcpNewReno::processRexmitTimer(), inet::tcp::TcpReno::processRexmitTimer(), inet::tcp::TcpTahoe::processRexmitTimer(), inet::tcp::TcpWestwood::processRexmitTimer(), inet::tcp::TcpVegas::processRexmitTimer(), and processTimer().

◆ processTimer()

void inet::tcp::TcpBaseAlg::processTimer ( cMessage *  timer,
TcpEventCode event 
)
overridevirtual

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

Implements inet::tcp::TcpAlgorithm.

195 {
196  if (timer == rexmitTimer)
197  processRexmitTimer(event);
198  else if (timer == persistTimer)
199  processPersistTimer(event);
200  else if (timer == delayedAckTimer)
201  processDelayedAckTimer(event);
202  else if (timer == keepAliveTimer)
203  processKeepAliveTimer(event);
204  else
205  throw cRuntimeError(timer, "unrecognized timer");
206 }

◆ receivedAckForDataNotYetSent()

void inet::tcp::TcpBaseAlg::receivedAckForDataNotYetSent ( uint32_t  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.

583 {
584  // Note: In this case no immediate ACK will be send because not mentioned
585  // in [Stevens, W.R.: TCP/IP Illustrated, Volume 2, page 861].
586  // To force immediate ACK use:
587 // state->ack_now = true;
588 // tcpEV << "ACK acks something not yet sent, sending immediate ACK\n";
589  EV_INFO << "ACK acks something not yet sent, sending ACK\n";
590  conn->sendAck();
591 }

◆ receivedDataAck()

void inet::tcp::TcpBaseAlg::receivedDataAck ( uint32_t  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::DcTcp, inet::tcp::TcpReno, and inet::tcp::TcpNewReno.

484 {
485  if (!state->ts_enabled) {
486  // if round-trip time measurement is running, check if rtseq has been acked
487  if (state->rtseq_sendtime != 0 && seqLess(state->rtseq, state->snd_una)) {
488  // print value
489  EV_DETAIL << "Round-trip time measured on rtseq=" << state->rtseq << ": "
490  << floor((simTime() - state->rtseq_sendtime) * 1000 + 0.5) << "ms\n";
491 
492  rttMeasurementComplete(state->rtseq_sendtime, simTime()); // update RTT variables with new value
493 
494  // measurement finished
495  state->rtseq_sendtime = 0;
496  }
497  }
498 
499  //
500  // handling of retransmission timer: if the ACK is for the last segment sent
501  // (no data in flight), cancel the timer, otherwise restart the timer
502  // with the current RTO value.
503  //
504  if (state->snd_una == state->snd_max) {
505  if (rexmitTimer->isScheduled()) {
506  EV_INFO << "ACK acks all outstanding segments, cancel REXMIT timer\n";
508  }
509  else
510  EV_INFO << "There were no outstanding segments, nothing new in this ACK.\n";
511  }
512  else {
513  EV_INFO << "ACK acks some but not all outstanding segments ("
514  << (state->snd_max - state->snd_una) << " bytes outstanding), "
515  << "restarting REXMIT timer\n";
518  }
519 
520  //
521  // handling of PERSIST timer:
522  // If data sender received a zero-sized window, check retransmission timer.
523  // If retransmission timer is not scheduled, start PERSIST timer if not already
524  // running.
525  //
526  // If data sender received a non zero-sized window, check PERSIST timer.
527  // If PERSIST timer is scheduled, cancel PERSIST timer.
528  //
529  if (state->snd_wnd == 0) { // received zero-sized window?
530  if (rexmitTimer->isScheduled()) {
531  if (persistTimer->isScheduled()) {
532  EV_INFO << "Received zero-sized window and REXMIT timer is running therefore PERSIST timer is canceled.\n";
534  state->persist_factor = 0;
535  }
536  else
537  EV_INFO << "Received zero-sized window and REXMIT timer is running therefore PERSIST timer is not started.\n";
538  }
539  else {
540  if (!persistTimer->isScheduled()) {
541  EV_INFO << "Received zero-sized window therefore PERSIST timer is started.\n";
542  conn->scheduleAfter(state->persist_timeout, persistTimer);
543  }
544  else
545  EV_INFO << "Received zero-sized window and PERSIST timer is already running.\n";
546  }
547  }
548  else { // received non zero-sized window?
549  if (persistTimer->isScheduled()) {
550  EV_INFO << "Received non zero-sized window therefore PERSIST timer is canceled.\n";
552  state->persist_factor = 0;
553  }
554  }
555 
556  //
557  // Leave congestion window management and possible sending data to
558  // subclasses (e.g. TcpTahoe, TcpReno).
559  //
560  // That is, subclasses will redefine this method, call us, then perform
561  // window adjustments and send data (if there's room in the window).
562  //
563 }

Referenced by inet::tcp::TcpNewReno::receivedDataAck(), inet::tcp::DcTcp::receivedDataAck(), inet::tcp::TcpReno::receivedDataAck(), inet::tcp::TcpTahoe::receivedDataAck(), inet::tcp::TcpNoCongestionControl::receivedDataAck(), inet::tcp::TcpWestwood::receivedDataAck(), and inet::tcp::TcpVegas::receivedDataAck().

◆ receivedDuplicateAck()

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::TcpReno, and inet::tcp::TcpNewReno.

566 {
567  EV_INFO << "Duplicate ACK #" << state->dupacks << "\n";
568 
569  bool fullSegmentsOnly = state->nagle_enabled && state->snd_una != state->snd_max;
570  if (state->dupacks < state->dupthresh && state->limited_transmit_enabled) // DUPTRESH = 3
571  conn->sendOneNewSegment(fullSegmentsOnly, state->snd_cwnd); // RFC 3042
572 
573  //
574  // Leave to subclasses (e.g. TcpTahoe, TcpReno) whatever they want to do
575  // on duplicate Acks.
576  //
577  // That is, subclasses will redefine this method, call us, then perform
578  // whatever action they want to do on dupAcks (e.g. retransmitting one segment).
579  //
580 }

Referenced by inet::tcp::TcpNewReno::receivedDuplicateAck(), inet::tcp::TcpReno::receivedDuplicateAck(), inet::tcp::TcpTahoe::receivedDuplicateAck(), inet::tcp::TcpWestwood::receivedDuplicateAck(), and inet::tcp::TcpVegas::receivedDuplicateAck().

◆ receivedOutOfOrderSegment()

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.

438 {
439  state->ack_now = true;
440  EV_INFO << "Out-of-order segment, sending immediate ACK\n";
441  conn->sendAck();
442 }

◆ receiveSeqChanged()

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.

445 {
446  // If we send a data segment already (with the updated seqNo) there is no need to send an additional ACK
447  if (state->full_sized_segment_counter == 0 && !state->ack_now && state->last_ack_sent == state->rcv_nxt && !delayedAckTimer->isScheduled()) { // ackSent?
448 // tcpEV << "ACK has already been sent (possibly piggybacked on data)\n";
449  }
450  else {
451  // RFC 2581, page 6:
452  // "3.2 Fast Retransmit/Fast Recovery
453  // (...)
454  // In addition, a TCP receiver SHOULD send an immediate ACK
455  // when the incoming segment fills in all or part of a gap in the
456  // sequence space."
457  if (state->lossRecovery)
458  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
459 
460  if (!state->delayed_acks_enabled) { // delayed ACK disabled
461  EV_INFO << "rcv_nxt changed to " << state->rcv_nxt << ", (delayed ACK disabled) sending ACK now\n";
462  conn->sendAck();
463  }
464  else { // delayed ACK enabled
465  if (state->ack_now) {
466  EV_INFO << "rcv_nxt changed to " << state->rcv_nxt << ", (delayed ACK enabled, but ack_now is set) sending ACK now\n";
467  conn->sendAck();
468  }
469  // RFC 1122, page 96: "in a stream of full-sized segments there SHOULD be an ACK for at least every second segment."
470  else if (state->full_sized_segment_counter >= 2) {
471  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";
472  conn->sendAck();
473  }
474  else {
475  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";
476  if (!delayedAckTimer->isScheduled()) // schedule delayed ACK timer if not already running
477  conn->scheduleAfter(DELAYED_ACK_TIMEOUT, delayedAckTimer);
478  }
479  }
480  }
481 }

◆ restartRexmitTimer()

void inet::tcp::TcpBaseAlg::restartRexmitTimer ( )
overridevirtual

◆ rttMeasurementComplete()

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)

346 {
347  //
348  // Jacobson's algorithm for estimating RTT and adaptively setting RTO.
349  //
350  // Note: this implementation calculates in doubles. An impl. which uses
351  // 500ms ticks is available from old tcpmodule.cc:calcRetransTimer().
352  //
353 
354  // update smoothed RTT estimate (srtt) and variance (rttvar)
355  const double g = 0.125; // 1 / 8; (1 - alpha) where alpha == 7 / 8;
356  simtime_t newRTT = tAcked - tSent;
357 
358  simtime_t& srtt = state->srtt;
359  simtime_t& rttvar = state->rttvar;
360 
361  simtime_t err = newRTT - srtt;
362 
363  srtt += g * err;
364  rttvar += g * (fabs(err) - rttvar);
365 
366  // assign RTO (here: rexmit_timeout) a new value
367  simtime_t rto = srtt + 4 * rttvar;
368 
369  if (rto > MAX_REXMIT_TIMEOUT)
370  rto = MAX_REXMIT_TIMEOUT;
371  else if (rto < MIN_REXMIT_TIMEOUT)
372  rto = MIN_REXMIT_TIMEOUT;
373 
374  state->rexmit_timeout = rto;
375 
376  // record statistics
377  EV_DETAIL << "Measured RTT=" << (newRTT * 1000) << "ms, updated SRTT=" << (srtt * 1000)
378  << "ms, new RTO=" << (rto * 1000) << "ms\n";
379 
380  conn->emit(rttSignal, newRTT);
381  conn->emit(srttSignal, srtt);
382  conn->emit(rttvarSignal, rttvar);
383  conn->emit(rtoSignal, rto);
384 }

Referenced by receivedDataAck(), and rttMeasurementCompleteUsingTS().

◆ rttMeasurementCompleteUsingTS()

void inet::tcp::TcpBaseAlg::rttMeasurementCompleteUsingTS ( uint32_t  echoedTS)
overrideprotectedvirtual

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

Implements inet::tcp::TcpAlgorithm.

387 {
388  ASSERT(state->ts_enabled);
389 
390  // Note: The TS option is using uint32_t values (ms precision) therefore we convert the current simTime also to a uint32_t value (ms precision)
391  // and then convert back to simtime_t to use rttMeasurementComplete() to update srtt and rttvar
392  uint32_t now = conn->convertSimtimeToTS(simTime());
393  simtime_t tSent = conn->convertTSToSimtime(echoedTS);
394  simtime_t tAcked = conn->convertTSToSimtime(now);
395  rttMeasurementComplete(tSent, tAcked);
396 }

◆ segmentRetransmitted()

void inet::tcp::TcpBaseAlg::segmentRetransmitted ( uint32_t  fromseq,
uint32_t  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.

625 {
626 }

Referenced by inet::tcp::TcpWestwood::segmentRetransmitted(), and inet::tcp::TcpVegas::segmentRetransmitted().

◆ sendCommandInvoked()

void inet::tcp::TcpBaseAlg::sendCommandInvoked ( )
overridevirtual

Called after user sent TCP_C_SEND command to us.

Implements inet::tcp::TcpAlgorithm.

432 {
433  // try sending
434  sendData(true);
435 }

Referenced by inet::tcp::TcpNoCongestionControl::sendData().

◆ sendData()

bool inet::tcp::TcpBaseAlg::sendData ( bool  sendCommandInvoked)
protectedvirtual

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

Reimplemented in inet::tcp::TcpNoCongestionControl.

399 {
400  // RFC 2581, pages 7 and 8: "When TCP has not received a segment for
401  // more than one retransmission timeout, cwnd is reduced to the value
402  // of the restart window (RW) before transmission begins.
403  // For the purposes of this standard, we define RW = IW.
404  // (...)
405  // Using the last time a segment was received to determine whether or
406  // not to decrease cwnd fails to deflate cwnd in the common case of
407  // persistent HTTP connections [HTH98].
408  // (...)
409  // Therefore, a TCP SHOULD set cwnd to no more than RW before beginning
410  // transmission if the TCP has not sent data in an interval exceeding
411  // the retransmission timeout."
412  if (!conn->isSendQueueEmpty()) { // do we have any data to send?
413  if ((simTime() - state->time_last_data_sent) > state->rexmit_timeout) {
414  // RFC 5681, page 11: "For the purposes of this standard, we define RW = min(IW,cwnd)."
416  state->snd_cwnd = std::min(std::min(4 * state->snd_mss, std::max(2 * state->snd_mss, (uint32_t)4380)), state->snd_cwnd);
417  else
419 
420  EV_INFO << "Restarting idle connection, CWND is set to " << state->snd_cwnd << "\n";
421  }
422  }
423 
424  //
425  // Send window is effectively the minimum of the congestion window (cwnd)
426  // and the advertised window (snd_wnd).
427  //
428  return conn->sendData(state->snd_cwnd);
429 }

Referenced by established(), inet::tcp::TcpNewReno::receivedDataAck(), inet::tcp::DcTcp::receivedDataAck(), inet::tcp::TcpReno::receivedDataAck(), inet::tcp::TcpTahoe::receivedDataAck(), inet::tcp::TcpWestwood::receivedDataAck(), inet::tcp::TcpVegas::receivedDataAck(), inet::tcp::TcpNewReno::receivedDuplicateAck(), inet::tcp::TcpReno::receivedDuplicateAck(), inet::tcp::TcpWestwood::receivedDuplicateAck(), inet::tcp::TcpVegas::receivedDuplicateAck(), and sendCommandInvoked().

◆ shouldMarkAck()

bool inet::tcp::TcpBaseAlg::shouldMarkAck ( )
overridevirtual

Called before sending ACK.

Determines whether to set ECE bit.

Implements inet::tcp::TcpAlgorithm.

Reimplemented in inet::tcp::DcTcp.

637 {
638 
639  // rfc-3168, pages 19-20:
640  // When TCP receives a CE data packet at the destination end-system, the
641  // TCP data receiver sets the ECN-Echo flag in the TCP header of the
642  // subsequent ACK packet.
643  // ...
644  // After a TCP receiver sends an ACK packet with the ECN-Echo bit set,
645  // that TCP receiver continues to set the ECN-Echo flag in all the ACK
646  // packets it sends (whether they acknowledge CE data packets or non-CE
647  // data packets) until it receives a CWR packet (a packet with the CWR
648  // flag set). After the receipt of the CWR packet, acknowledgments for
649  // subsequent non-CE data packets do not have the ECN-Echo flag set.
650 
651  if (state && state->ect) {
652  if (state->gotCeIndication) {
653  EV_INFO << "Received CE... ";
654  if (state->ecnEchoState)
655  EV_INFO << "Already in ecnEcho state\n";
656  else {
657  state->ecnEchoState = true;
658  EV << "Entering ecnEcho state\n";
659  }
660  state->gotCeIndication = false;
661  }
662  return state->ecnEchoState;
663  }
664  return false;
665 }

◆ startRexmitTimer()

void inet::tcp::TcpBaseAlg::startRexmitTimer ( )
protectedvirtual

Start REXMIT timer and initialize retransmission variables.

336 {
337  // start counting retransmissions for this seq number.
338  // Note: state->rexmit_timeout is set from rttMeasurementComplete().
339  state->rexmit_count = 0;
340 
341  // schedule timer
342  conn->scheduleAfter(state->rexmit_timeout, rexmitTimer);
343 }

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

Member Data Documentation

◆ cwndSignal

◆ delayedAckTimer

cMessage* inet::tcp::TcpBaseAlg::delayedAckTimer
protected

◆ keepAliveTimer

cMessage* inet::tcp::TcpBaseAlg::keepAliveTimer
protected

◆ numRtosSignal

simsignal_t inet::tcp::TcpBaseAlg::numRtosSignal = cComponent::registerSignal("numRtos")
staticprotected

Referenced by processRexmitTimer().

◆ persistTimer

cMessage* inet::tcp::TcpBaseAlg::persistTimer
protected

◆ rexmitTimer

◆ rtoSignal

simsignal_t inet::tcp::TcpBaseAlg::rtoSignal = cComponent::registerSignal("rto")
staticprotected

Referenced by rttMeasurementComplete().

◆ rttSignal

simsignal_t inet::tcp::TcpBaseAlg::rttSignal = cComponent::registerSignal("rtt")
staticprotected

Referenced by rttMeasurementComplete().

◆ rttvarSignal

simsignal_t inet::tcp::TcpBaseAlg::rttvarSignal = cComponent::registerSignal("rttvar")
staticprotected

Referenced by rttMeasurementComplete().

◆ srttSignal

simsignal_t inet::tcp::TcpBaseAlg::srttSignal = cComponent::registerSignal("srtt")
staticprotected

Referenced by rttMeasurementComplete().

◆ ssthreshSignal

◆ state


The documentation for this class was generated from the following files:
inet::tcp::TcpConnection::sendProbe
virtual bool sendProbe()
Utility: sends 1 bytes as "probe", called by the "persist" mechanism.
Definition: TcpConnectionUtil.cc:930
inet::tcp::TcpBaseAlg::processKeepAliveTimer
virtual void processKeepAliveTimer(TcpEventCode &event)
Definition: TcpBaseAlg.cc:319
MIN_REXMIT_TIMEOUT
#define MIN_REXMIT_TIMEOUT
Definition: TcpBaseAlg.cc:34
inet::tcp::TcpBaseAlg::cancelEvent
cMessage * cancelEvent(cMessage *msg)
Utility function.
Definition: TcpBaseAlg.h:142
inet::tcp::TcpStateVariables::full_sized_segment_counter
uint32_t full_sized_segment_counter
Definition: TcpConnection.h:184
inet::tcp::TcpConnection::convertTSToSimtime
static simtime_t convertTSToSimtime(uint32_t timestamp)
Utility: converts a given timestamp (TS) to a simtime.
Definition: TcpConnectionUtil.cc:1597
inet::tcp::TcpBaseAlg::processRexmitTimer
virtual void processRexmitTimer(TcpEventCode &event)
Definition: TcpBaseAlg.cc:208
inet::tcp::TcpBaseAlg::rttvarSignal
static simsignal_t rttvarSignal
Definition: TcpBaseAlg.h:105
inet::tcp::TcpBaseAlgStateVariables::persist_factor
uint persist_factor
persist factor
Definition: TcpBaseAlg.h:34
inet::tcp::TcpAlgorithm::initialize
virtual void initialize()
Should be redefined to initialize the object: create timers, etc.
Definition: TcpAlgorithm.h:70
inet::tcp::TcpStateVariables::limited_transmit_enabled
bool limited_transmit_enabled
Definition: TcpConnection.h:181
inet::tcp::TcpBaseAlgStateVariables::str
virtual std::string str() const override
Definition: TcpBaseAlg.cc:67
inet::tcp::TcpConnection::sendAck
virtual void sendAck()
Utility: send ACK.
Definition: TcpConnectionUtil.cc:679
inet::tcp::TcpBaseAlgStateVariables::snd_cwnd
uint32_t snd_cwnd
congestion window
Definition: TcpBaseAlg.h:40
inet::sctp::min
double min(const double a, const double b)
Returns the minimum of a and b.
Definition: SctpAssociation.h:261
inet::tcp::TcpBaseAlg::state
TcpBaseAlgStateVariables *& state
Definition: TcpBaseAlg.h:94
inet::tcp::TcpBaseAlgStateVariables::numRtos
uint32_t numRtos
number of RTOs
Definition: TcpBaseAlg.h:57
inet::tcp::TcpStateVariables::dupacks
uint32_t dupacks
Definition: TcpConnection.h:236
inet::tcp::TcpBaseAlg::rttMeasurementComplete
virtual void rttMeasurementComplete(simtime_t tSent, simtime_t tAcked)
Update state vars with new measured RTT value.
Definition: TcpBaseAlg.cc:345
inet::tcp::TcpStateVariables::recoveryPoint
uint32_t recoveryPoint
Definition: TcpConnection.h:226
inet::tcp::TcpBaseAlgStateVariables::srtt
simtime_t srtt
round-trip time estimation (Jacobson's algorithm)
Definition: TcpBaseAlg.h:51
inet::tcp::TcpConnection::signalConnectionTimeout
virtual void signalConnectionTimeout()
Utility: signal to user that connection timed out.
Definition: TcpConnectionUtil.cc:336
inet::tcp::TcpBaseAlgStateVariables::rexmit_timeout
simtime_t rexmit_timeout
current retransmission timeout (aka RTO)
Definition: TcpBaseAlg.h:29
inet::tcp::seqLess
bool seqLess(uint32_t a, uint32_t b)
Definition: TcpHeader.h:21
inet::tcp::TcpStateVariables::ecnEchoState
bool ecnEchoState
Definition: TcpConnection.h:249
inet::tcp::TcpBaseAlg::persistTimer
cMessage * persistTimer
Definition: TcpBaseAlg.h:97
inet::tcp::TcpStateVariables::dupthresh
uint32_t dupthresh
Definition: TcpConnection.h:261
inet::tcp::TcpAlgorithm::TcpAlgorithm
TcpAlgorithm()
Ctor.
Definition: TcpAlgorithm.h:41
inet::tcp::TcpStateVariables::snd_wnd
uint32_t snd_wnd
Definition: TcpConnection.h:150
inet::tcp::TcpStateVariables::ts_enabled
bool ts_enabled
Definition: TcpConnection.h:207
inet::tcp::TcpBaseAlgStateVariables::rttvar
simtime_t rttvar
variance of round-trip time
Definition: TcpBaseAlg.h:52
inet::units::units::g
milli< kg >::type g
Definition: Units.h:1071
inet::tcp::TcpStateVariables::lossRecovery
bool lossRecovery
Definition: TcpConnection.h:229
inet::tcp::TcpBaseAlg::processDelayedAckTimer
virtual void processDelayedAckTimer(TcpEventCode &event)
Definition: TcpBaseAlg.cc:313
inet::tcp::TcpBaseAlg::rttSignal
static simsignal_t rttSignal
Definition: TcpBaseAlg.h:103
inet::tcp::TcpBaseAlg::processPersistTimer
virtual void processPersistTimer(TcpEventCode &event)
Definition: TcpBaseAlg.cc:285
inet::tcp::TcpStateVariables::last_ack_sent
uint32_t last_ack_sent
Definition: TcpConnection.h:211
inet::tcp::TcpBaseAlg::startRexmitTimer
virtual void startRexmitTimer()
Start REXMIT timer and initialize retransmission variables.
Definition: TcpBaseAlg.cc:335
inet::tcp::TcpStateVariables::nagle_enabled
bool nagle_enabled
Definition: TcpConnection.h:179
inet::tcp::TcpSackRexmitQueue::resetSackedBit
virtual void resetSackedBit()
Called when REXMIT timer expired.
Definition: TcpSackRexmitQueue.cc:290
inet::tcp::TcpStateVariables::time_last_data_sent
simtime_t time_last_data_sent
Definition: TcpConnection.h:212
inet::tcp::TcpAlgorithm::conn
TcpConnection * conn
Definition: TcpAlgorithm.h:26
inet::tcp::TcpBaseAlgStateVariables::rtseq
uint32_t rtseq
round-trip time measurements
Definition: TcpBaseAlg.h:45
inet::tcp::TcpBaseAlg::keepAliveTimer
cMessage * keepAliveTimer
Definition: TcpBaseAlg.h:99
inet::tcp::TcpStateVariables::ect
bool ect
Definition: TcpConnection.h:253
inet::tcp::TcpBaseAlg::delayedAckTimer
cMessage * delayedAckTimer
Definition: TcpBaseAlg.h:98
DELAYED_ACK_TIMEOUT
#define DELAYED_ACK_TIMEOUT
Definition: TcpBaseAlg.cc:32
MIN_PERSIST_TIMEOUT
#define MIN_PERSIST_TIMEOUT
Definition: TcpBaseAlg.cc:37
inet::tcp::TcpStateVariables::sack_enabled
bool sack_enabled
Definition: TcpConnection.h:216
inet::tcp::TcpBaseAlg::numRtosSignal
static simsignal_t numRtosSignal
Definition: TcpBaseAlg.h:107
inet::tcp::TcpBaseAlgStateVariables::rtseq_sendtime
simtime_t rtseq_sendtime
time when rtseq was sent (0 if RTT measurement is not running)
Definition: TcpBaseAlg.h:46
inet::tcp::TcpBaseAlg::rexmitTimer
cMessage * rexmitTimer
Definition: TcpBaseAlg.h:96
inet::tcp::TcpConnection::isSendQueueEmpty
virtual bool isSendQueueEmpty()
Utility: checks if send queue is empty (no data to send).
Definition: TcpConnectionUtil.cc:1605
inet::tcp::TcpBaseAlg::srttSignal
static simsignal_t srttSignal
Definition: TcpBaseAlg.h:104
inet::sctp::max
double max(const double a, const double b)
Returns the maximum of a and b.
Definition: SctpAssociation.h:266
inet::tcp::TcpBaseAlgStateVariables::persist_timeout
simtime_t persist_timeout
current persist timeout
Definition: TcpBaseAlg.h:35
inet::tcp::TcpConnection::sendData
virtual bool sendData(uint32_t congestionWindow)
Utility: Send data from sendQueue, at most congestionWindow.
Definition: TcpConnectionUtil.cc:848
MAX_REXMIT_COUNT
#define MAX_REXMIT_COUNT
Definition: TcpBaseAlg.cc:33
inet::tcp::TcpStateVariables::snd_mss
uint32_t snd_mss
Definition: TcpConnection.h:142
inet::tcp::TcpBaseAlgStateVariables::rexmit_count
int rexmit_count
retransmit count
Definition: TcpBaseAlg.h:28
inet::tcp::TcpStateVariables::increased_IW_enabled
bool increased_IW_enabled
Definition: TcpConnection.h:182
inet::tcp::TcpStateVariables::syn_rexmit_count
int syn_rexmit_count
Definition: TcpConnection.h:165
inet::tcp::TCP_E_ABORT
@ TCP_E_ABORT
Definition: TcpConnection.h:75
MAX_PERSIST_TIMEOUT
#define MAX_PERSIST_TIMEOUT
Definition: TcpBaseAlg.cc:38
inet::tcp::TcpBaseAlg::sendData
virtual bool sendData(bool sendCommandInvoked)
Send data, observing Nagle's algorithm and congestion window.
Definition: TcpBaseAlg.cc:398
inet::tcp::TcpBaseAlg::rtoSignal
static simsignal_t rtoSignal
Definition: TcpBaseAlg.h:106
inet::tcp::TcpStateVariables::rcv_nxt
uint32_t rcv_nxt
Definition: TcpConnection.h:157
inet::tcp::TcpSackRexmitQueue::resetRexmittedBit
virtual void resetRexmittedBit()
Called when REXMIT timer expired.
Definition: TcpSackRexmitQueue.cc:296
inet::tcp::TcpStateVariables::ack_now
bool ack_now
Definition: TcpConnection.h:185
inet::tcp::TcpConnection::convertSimtimeToTS
static uint32_t convertSimtimeToTS(simtime_t simtime)
Utility: converts a given simtime to a timestamp (TS).
Definition: TcpConnectionUtil.cc:1589
inet::tcp::TcpStateVariables::gotCeIndication
bool gotCeIndication
Definition: TcpConnection.h:252
inet::tcp::TcpStateVariables::snd_una
uint32_t snd_una
Definition: TcpConnection.h:147
inet::tcp::TcpAlgorithm::state
TcpStateVariables * state
Definition: TcpAlgorithm.h:27
inet::tcp::TcpConnection::rexmitQueue
TcpSackRexmitQueue * rexmitQueue
Definition: TcpConnection.h:373
MAX_REXMIT_TIMEOUT
#define MAX_REXMIT_TIMEOUT
Definition: TcpBaseAlg.cc:36
inet::tcp::TcpStateVariables::snd_max
uint32_t snd_max
Definition: TcpConnection.h:149
inet::tcp::TcpConnection::sendOneNewSegment
virtual void sendOneNewSegment(bool fullSegmentsOnly, uint32_t congestionWindow)
Utility: send one new segment from snd_max if allowed (RFC 3042).
Definition: TcpConnectionUtil.cc:1513
inet::tcp::TcpStateVariables::delayed_acks_enabled
bool delayed_acks_enabled
Definition: TcpConnection.h:180