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

#include <TcpWestwood.h>

Inheritance diagram for inet::tcp::TcpWestwood:
inet::tcp::TcpBaseAlg inet::tcp::TcpAlgorithm

Public Member Functions

 TcpWestwood ()
 Ctor. More...
 
virtual void receivedDataAck (uint32_t 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...
 
virtual void dataSent (uint32_t fromseq) override
 Called after we send data. More...
 
virtual void segmentRetransmitted (uint32_t fromseq, uint32_t toseq) override
 Called after we retransmitted segment. 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_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 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...
 
- 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 TCPvegasStateVariables object. More...
 
virtual void recalculateSlowStartThreshold ()
 Utility function to recalculate ssthresh. More...
 
virtual void processRexmitTimer (TcpEventCode &event) override
 Redefine what should happen on retransmission. More...
 
virtual void recalculateBWE (uint32_t cumul_ack)
 Recalculate BWE. More...
 
- Protected Member Functions inherited from inet::tcp::TcpBaseAlg
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...
 

Protected Attributes

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

Additional Inherited Members

- Static Protected Attributes inherited from inet::tcp::TcpBaseAlg
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")
 

Constructor & Destructor Documentation

◆ TcpWestwood()

inet::tcp::TcpWestwood::TcpWestwood ( )

Ctor.

51  : TcpBaseAlg(), state((TcpWestwoodStateVariables *&)TcpAlgorithm::state)
52 {
53 }

Member Function Documentation

◆ createStateVariables()

virtual TcpStateVariables* inet::tcp::TcpWestwood::createStateVariables ( )
inlineoverrideprotectedvirtual

Create and return a TCPvegasStateVariables object.

Implements inet::tcp::TcpAlgorithm.

48  {
49  return new TcpWestwoodStateVariables();
50  }

◆ dataSent()

void inet::tcp::TcpWestwood::dataSent ( uint32_t  fromseq)
overridevirtual

Called after we send data.

Reimplemented from inet::tcp::TcpBaseAlg.

278 {
279  TcpBaseAlg::dataSent(fromseq);
280 
281  // save time when packet is sent
282  // fromseq is the seq number of the 1st sent byte
283 
284  simtime_t sendtime = simTime();
286  state->regions.set(fromseq, state->snd_max, sendtime);
287 }

◆ processRexmitTimer()

void inet::tcp::TcpWestwood::processRexmitTimer ( TcpEventCode event)
overrideprotectedvirtual

Redefine what should happen on retransmission.

Reimplemented from inet::tcp::TcpBaseAlg.

81 {
83 
84  if (event == TCP_E_ABORT)
85  return;
86 
87  // TCP Westwood: congestion control with faster recovery. S. Mascolo, C. Casetti, M. Gerla, S.S. Lee, M. Sanadidi
88  // After REXMIT timeout in TCP Westwood: a increases from 1 to 4, in steps of 1 during slow start,
89  // and is set to 1 in cong. avoidance.
90  // the cong. window is reset to 1 after a timeout, as is done by TCP Reno. Conservative. Reaseon: fairness.
91 
92  if (state->snd_cwnd < state->ssthresh) { // Slow start
93  state->w_a = state->w_a + 1;
94  if (state->w_a > 4)
95  state->w_a = 4;
96  }
97  else { // Cong. avoidance
98  state->w_a = 1;
99  }
100 
102  if (state->ssthresh < 2 * state->snd_mss)
103  state->ssthresh = 2 * state->snd_mss;
104 
106 
107  conn->emit(cwndSignal, state->snd_cwnd);
108 
109  state->afterRto = true;
110  conn->retransmitOneSegment(true);
111 }

◆ recalculateBWE()

void inet::tcp::TcpWestwood::recalculateBWE ( uint32_t  cumul_ack)
protectedvirtual

Recalculate BWE.

65 {
66  simtime_t currentTime = simTime();
67  simtime_t timeAck = currentTime - state->w_lastAckTime;
68 
69  // Update BWE
70  if (timeAck > 0) {
71  double old_sample_bwe = state->w_sample_bwe;
72  double old_bwe = state->w_bwe;
73  state->w_sample_bwe = (cumul_ack) / timeAck;
74  state->w_bwe = (19.0 / 21.0) * old_bwe + (1.0 / 21.0) * (state->w_sample_bwe + old_sample_bwe);
75  EV_DEBUG << "recalculateBWE(), new w_bwe=" << state->w_bwe << "\n";
76  }
77  state->w_lastAckTime = currentTime;
78 }

Referenced by receivedDataAck(), and receivedDuplicateAck().

◆ recalculateSlowStartThreshold()

void inet::tcp::TcpWestwood::recalculateSlowStartThreshold ( )
protectedvirtual

Utility function to recalculate ssthresh.

56 {
57  state->ssthresh = (uint32_t)((state->w_bwe * SIMTIME_DBL(state->w_RTTmin)) / (state->w_a));
58 
60 
61  EV_DEBUG << "recalculateSlowStartThreshold(), ssthresh=" << state->ssthresh << "\n";
62 }

Referenced by processRexmitTimer(), and receivedDuplicateAck().

◆ receivedDataAck()

void inet::tcp::TcpWestwood::receivedDataAck ( uint32_t  firstSeqAcked)
overridevirtual

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

Reimplemented from inet::tcp::TcpBaseAlg.

114 {
115  TcpBaseAlg::receivedDataAck(firstSeqAcked);
116 
118  const TcpSegmentTransmitInfoList::Item *found = state->regions.get(firstSeqAcked);
119 
120  if (found != nullptr) {
121  simtime_t currentTime = simTime();
122  simtime_t newRTT = currentTime - found->getFirstSentTime();
123 
124  // Update RTTmin
125  if (newRTT < state->w_RTTmin && newRTT > 0 && found->getTransmitCount() == 1)
126  state->w_RTTmin = newRTT;
127 
128  // cumul_ack: cumulative ack's that acks 2 or more pkts count 1,
129  // because DUPACKs count them
130  uint32_t cumul_ack = state->snd_una - firstSeqAcked; // acked bytes
131  if ((state->dupacks * state->snd_mss) >= cumul_ack)
132  cumul_ack = state->snd_mss; // cumul_ack = 1:
133  else
134  cumul_ack -= (state->dupacks * state->snd_mss);
135 
136  // security check: if previous steps are right cumul_ack shoudl be > 2:
137  if (cumul_ack > (2 * state->snd_mss))
138  cumul_ack = 2 * state->snd_mss;
139 
140  recalculateBWE(cumul_ack);
141  } // Closes if w_sendtime != nullptr
142 
143  // Same behavior of Reno during fast recovery, slow start and cong. avoidance
144 
145  if (state->dupacks >= state->dupthresh) {
146  //
147  // Perform Fast Recovery: set cwnd to ssthresh (deflating the window).
148  //
149  EV_DETAIL << "Fast Recovery: setting cwnd to ssthresh=" << state->ssthresh << "\n";
151 
152  conn->emit(cwndSignal, state->snd_cwnd);
153  }
154  else {
155  //
156  // Perform slow start and congestion avoidance.
157  //
158  if (state->snd_cwnd < state->ssthresh) {
159  EV_DETAIL << "cwnd <= ssthresh: Slow Start: increasing cwnd by one SMSS bytes to ";
160 
161  // perform Slow Start. RFC 2581: "During slow start, a TCP increments cwnd
162  // by at most SMSS bytes for each ACK received that acknowledges new data."
164 
165  // Note: we could increase cwnd based on the number of bytes being
166  // acknowledged by each arriving ACK, rather than by the number of ACKs
167  // that arrive. This is called "Appropriate Byte Counting" (ABC) and is
168  // described in RFC 3465. This RFC is experimental and probably not
169  // implemented in real-life TCPs, hence it's commented out. Also, the ABC
170  // RFC would require other modifications as well in addition to the
171  // two lines below.
172  //
173 // int bytesAcked = state->snd_una - firstSeqAcked;
174 // state->snd_cwnd += bytesAcked * state->snd_mss;
175 
176  conn->emit(cwndSignal, state->snd_cwnd);
177 
178  EV_DETAIL << "cwnd=" << state->snd_cwnd << "\n";
179  }
180  else {
181  // perform Congestion Avoidance (RFC 2581)
182  uint32_t incr = state->snd_mss * state->snd_mss / state->snd_cwnd;
183 
184  if (incr == 0)
185  incr = 1;
186 
187  state->snd_cwnd += incr;
188 
189  conn->emit(cwndSignal, state->snd_cwnd);
190 
191  //
192  // Note: some implementations use extra additive constant mss / 8 here
193  // which is known to be incorrect (RFC 2581 p5)
194  //
195  // Note 2: RFC 3465 (experimental) "Appropriate Byte Counting" (ABC)
196  // would require maintaining a bytes_acked variable here which we don't do
197  //
198 
199  EV_DETAIL << "cwnd > ssthresh: Congestion Avoidance: increasing cwnd linearly, to " << state->snd_cwnd << "\n";
200  }
201  }
202 
203  sendData(false);
204 }

◆ receivedDuplicateAck()

void inet::tcp::TcpWestwood::receivedDuplicateAck ( )
overridevirtual

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

Reimplemented from inet::tcp::TcpBaseAlg.

207 {
209 
210  {
211  // BWE calculation: dupack counts 1
212  uint32_t cumul_ack = state->snd_mss;
213  recalculateBWE(cumul_ack);
214  } // Closes if w_sendtime != nullptr
215 
216  if (state->dupacks == state->dupthresh) {
217  EV_DETAIL << "Westwood on dupAcks == DUPTHRESH(=" << state->dupthresh << ": Faster Retransmit \n";
218 
219  // TCP Westwood: congestion control with faster recovery. S. Mascolo, C. Casetti, M. Gerla, S.S. Lee, M. Sanadidi
220  // During the cong. avoidance phase we are probing for extra available bandwidth.
221  // Therefore, when n DUPACKS are received, it means that we have hit the network
222  // capacity. Thus, the slow start threshold is set equal to the available pipe size
223  // (BWE*RTTmin), the cong. window is set equal to ssthresh and the cong. avoidance phase
224  // is entered again to gently probe for new available bandwitdh.
225 
226  // During the slow start phase we are still probing for the available bandwidth.
227  // Therefore the BWE we obtain after n duplicate ACKs is used to set the slow start threshold.
228  // After ssthresh has been set, the cong. window is set equal to the slow start theshold only
229  // if cwin>ssthresh. In other words, during slow start, cwin still features an exponential
230  // increase as in the current implementation of TCP Reno.
231 
232  // a increases from 1 to 4 in steps of 0.25 every time 3 DUPACKS are received in slow start.
233  // while is set to 1 in cong. avoidance. (is initialized as 1).
234  // The purpose of the theshold reduction factor a is to dampen a possible overestimation of
235  // the available bandwidth. the more frequently a triple DUPACK is received during slow start,
236  // the bigger the reduction factor becomes.
237  // a is restored to 1 in cong. avoidance: ssthresh was set correctly and there is no need to reduce
238  // the impact of BWE
239 
240  if (state->snd_cwnd < state->ssthresh) { // Slow start
241  state->w_a = state->w_a + 0.25;
242  if (state->w_a > 4)
243  state->w_a = 4;
244  }
245  else { // Cong. avoidance
246  state->w_a = 1;
247  }
248 
250  // reset cwnd to ssthresh, if larger
251  if (state->snd_cwnd > state->ssthresh)
253 
254  conn->emit(cwndSignal, state->snd_cwnd);
255 
256  EV_DETAIL << " set cwnd=" << state->snd_cwnd << ", ssthresh=" << state->ssthresh << "\n";
257 
258  // Fast Retransmission: retransmit missing segment without waiting
259  // for the REXMIT timer to expire
261  conn->retransmitOneSegment(false);
262 
263  sendData(false);
264  }
265  // Behavior like Reno:
266  else if (state->dupacks > state->dupthresh) {
267  // Westwood: like Reno
269  EV_DETAIL << "Westwood on dupAcks > DUPTHRESH(=" << state->dupthresh << ": Fast Recovery: inflating cwnd by SMSS, new cwnd=" << state->snd_cwnd << "\n";
270 
271  conn->emit(cwndSignal, state->snd_cwnd);
272 
273  sendData(false);
274  }
275 }

◆ segmentRetransmitted()

void inet::tcp::TcpWestwood::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.

Reimplemented from inet::tcp::TcpBaseAlg.

290 {
291  TcpBaseAlg::segmentRetransmitted(fromseq, toseq);
292 
293  state->regions.set(fromseq, toseq, simTime());
294 }

Member Data Documentation

◆ state


The documentation for this class was generated from the following files:
inet::tcp::TcpBaseAlg::cwndSignal
static simsignal_t cwndSignal
Definition: TcpBaseAlg.h:101
inet::tcp::TcpBaseAlg::TcpBaseAlg
TcpBaseAlg()
Ctor.
Definition: TcpBaseAlg.cc:95
inet::tcp::TcpBaseAlg::processRexmitTimer
virtual void processRexmitTimer(TcpEventCode &event)
Definition: TcpBaseAlg.cc:208
inet::tcp::TcpBaseAlgStateVariables::snd_cwnd
uint32_t snd_cwnd
congestion window
Definition: TcpBaseAlg.h:40
inet::tcp::TcpStateVariables::dupacks
uint32_t dupacks
Definition: TcpConnection.h:236
inet::tcp::TcpBaseAlg::segmentRetransmitted
virtual void segmentRetransmitted(uint32_t fromseq, uint32_t toseq) override
Called after we retransmitted segment.
Definition: TcpBaseAlg.cc:624
inet::tcp::TcpStateVariables::dupthresh
uint32_t dupthresh
Definition: TcpConnection.h:261
inet::tcp::TcpSegmentTransmitInfoList::clearTo
void clearTo(uint32_t endseg)
Definition: TcpSegmentTransmitInfoList.cc:75
inet::tcp::TcpBaseAlg::receivedDuplicateAck
virtual void receivedDuplicateAck() override
Called after we received a duplicate ACK (that is: ackNo == snd_una, no data in segment,...
Definition: TcpBaseAlg.cc:565
inet::tcp::TcpWestwood::recalculateSlowStartThreshold
virtual void recalculateSlowStartThreshold()
Utility function to recalculate ssthresh.
Definition: TcpWestwood.cc:55
inet::tcp::TcpSegmentTransmitInfoList::get
const Item * get(uint32_t seq) const
returns pointer to Item, or nullptr if not found
Definition: TcpSegmentTransmitInfoList.cc:64
inet::tcp::TcpWestwoodStateVariables::w_a
double w_a
Definition: TcpWestwood.h:31
inet::tcp::TcpAlgorithm::conn
TcpConnection * conn
Definition: TcpAlgorithm.h:26
inet::tcp::TcpBaseAlg::receivedDataAck
virtual void receivedDataAck(uint32_t firstSeqAcked) override
Called after we received an ACK which acked some data (that is, we could advance snd_una).
Definition: TcpBaseAlg.cc:483
inet::tcp::TcpStateVariables::afterRto
bool afterRto
Definition: TcpConnection.h:194
inet::tcp::TcpWestwood::recalculateBWE
virtual void recalculateBWE(uint32_t cumul_ack)
Recalculate BWE.
Definition: TcpWestwood.cc:64
inet::tcp::TcpStateVariables::snd_mss
uint32_t snd_mss
Definition: TcpConnection.h:142
inet::tcp::TcpWestwoodStateVariables::w_sample_bwe
double w_sample_bwe
Definition: TcpWestwood.h:36
inet::tcp::TcpWestwood::state
TcpWestwoodStateVariables *& state
Definition: TcpWestwood.h:44
inet::tcp::TcpWestwoodStateVariables::ssthresh
uint32_t ssthresh
slow start threshold
Definition: TcpWestwood.h:28
inet::tcp::TcpBaseAlg::dataSent
virtual void dataSent(uint32_t fromseq) override
Called after we sent data.
Definition: TcpBaseAlg.cc:603
inet::tcp::TcpSegmentTransmitInfoList::set
void set(uint32_t beg, uint32_t end, simtime_t sentTime)
Definition: TcpSegmentTransmitInfoList.cc:16
inet::tcp::TcpWestwoodStateVariables::w_lastAckTime
simtime_t w_lastAckTime
Definition: TcpWestwood.h:33
inet::tcp::TCP_E_ABORT
@ TCP_E_ABORT
Definition: TcpConnection.h:75
inet::tcp::TcpBaseAlg::restartRexmitTimer
virtual void restartRexmitTimer() override
Restart REXMIT timer.
Definition: TcpBaseAlg.cc:628
inet::tcp::TcpBaseAlg::sendData
virtual bool sendData(bool sendCommandInvoked)
Send data, observing Nagle's algorithm and congestion window.
Definition: TcpBaseAlg.cc:398
inet::tcp::TcpWestwoodStateVariables::w_RTTmin
simtime_t w_RTTmin
Definition: TcpWestwood.h:30
inet::tcp::TcpConnection::retransmitOneSegment
virtual void retransmitOneSegment(bool called_at_rto)
Utility: retransmit one segment from snd_una.
Definition: TcpConnectionUtil.cc:960
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::TcpBaseAlg::ssthreshSignal
static simsignal_t ssthreshSignal
Definition: TcpBaseAlg.h:102
inet::tcp::TcpWestwoodStateVariables::regions
TcpSegmentTransmitInfoList regions
Definition: TcpWestwood.h:38
inet::tcp::TcpWestwoodStateVariables::w_bwe
double w_bwe
Definition: TcpWestwood.h:35
inet::tcp::TcpStateVariables::snd_max
uint32_t snd_max
Definition: TcpConnection.h:149