A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tcp-illinois.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2016 ResiliNets, ITTC, University of Kansas
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Keerthi Ganta <keerthiganta@ku.edu>
7 * Truc Anh N. Nguyen <annguyen@ittc.ku.edu>
8 *
9 * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
10 * ResiliNets Research Group https://resilinets.org/
11 * Information and Telecommunication Technology Center (ITTC)
12 * and Department of Electrical Engineering and Computer Science
13 * The University of Kansas Lawrence, KS USA.
14 */
15
16#include "tcp-illinois.h"
17
18#include "tcp-socket-state.h"
19
20#include "ns3/log.h"
21
22namespace ns3
23{
24
25NS_LOG_COMPONENT_DEFINE("TcpIllinois");
27
28TypeId
30{
31 static TypeId tid = TypeId("ns3::TcpIllinois")
33 .AddConstructor<TcpIllinois>()
34 .SetGroupName("Internet")
35 .AddAttribute("AlphaMin",
36 "Minimum alpha threshold",
37 DoubleValue(0.3),
40 .AddAttribute("AlphaMax",
41 "Maximum alpha threshold",
42 DoubleValue(10.0),
45 .AddAttribute("AlphaBase",
46 "Alpha base threshold",
47 DoubleValue(1.0),
50 .AddAttribute("BetaMin",
51 "Minimum beta threshold",
52 DoubleValue(0.125),
55 .AddAttribute("BetaMax",
56 "Maximum beta threshold",
57 DoubleValue(0.5),
60 .AddAttribute("BetaBase",
61 "Beta base threshold",
62 DoubleValue(0.5),
65 .AddAttribute("WinThresh",
66 "Window threshold",
67 UintegerValue(15),
70 .AddAttribute("Theta",
71 "Theta threshold",
75 return tid;
76}
77
79 : TcpNewReno(),
80 m_sumRtt(Time(0)),
81 m_cntRtt(0),
82 m_baseRtt(Time::Max()),
83 m_maxRtt(Time::Min()),
84 m_endSeq(0),
85 m_rttAbove(false),
86 m_rttLow(0),
87 m_alphaMin(0.3),
88 m_alphaMax(10.0),
89 m_alphaBase(1.0),
90 m_alpha(m_alphaMax),
91 m_betaMin(0.125),
92 m_betaMax(0.5),
93 m_betaBase(0.5),
94 m_beta(m_betaBase),
95 m_winThresh(15),
96 m_theta(5),
97 m_ackCnt(0)
98{
99 NS_LOG_FUNCTION(this);
100}
101
103 : TcpNewReno(sock),
104 m_sumRtt(sock.m_sumRtt),
105 m_cntRtt(sock.m_cntRtt),
106 m_baseRtt(sock.m_baseRtt),
107 m_maxRtt(sock.m_maxRtt),
108 m_endSeq(sock.m_endSeq),
109 m_rttAbove(sock.m_rttAbove),
110 m_rttLow(sock.m_rttLow),
111 m_alphaMin(sock.m_alphaMin),
112 m_alphaMax(sock.m_alphaMax),
113 m_alphaBase(sock.m_alphaBase),
114 m_alpha(sock.m_alpha),
115 m_betaMin(sock.m_betaMin),
116 m_betaMax(sock.m_betaMax),
117 m_betaBase(sock.m_betaBase),
118 m_beta(sock.m_beta),
119 m_winThresh(sock.m_winThresh),
120 m_theta(sock.m_theta),
121 m_ackCnt(sock.m_ackCnt)
122{
123 NS_LOG_FUNCTION(this);
124}
125
130
131void
133{
134 NS_LOG_FUNCTION(this << cWnd);
135
136 if (cWnd < m_winThresh)
137 {
138 NS_LOG_INFO("cWnd < winThresh, set alpha & beta to base values");
139
142 }
143 else if (m_cntRtt > 0)
144 {
145 double dm = static_cast<double>(CalculateMaxDelay().GetMilliSeconds());
146 double da = static_cast<double>(CalculateAvgDelay().GetMilliSeconds());
147
148 NS_LOG_INFO("Updated to dm = " << dm << " da = " << da);
149
150 CalculateAlpha(da, dm);
151 CalculateBeta(da, dm);
152 }
153}
154
155void
157 const TcpSocketState::TcpCongState_t newState)
158{
159 NS_LOG_FUNCTION(this << tcb << newState);
160
161 if (newState == TcpSocketState::CA_LOSS)
162 {
165 m_rttLow = 0;
166 m_rttAbove = false;
167 Reset(tcb->m_nextTxSequence);
168 }
169}
170
171void
173{
174 NS_LOG_FUNCTION(this << segmentsAcked);
175
176 if (tcb->m_lastAckedSeq >= m_endSeq)
177 {
178 RecalcParam(tcb->m_cWnd);
179 Reset(tcb->m_nextTxSequence);
180 }
181
182 if (tcb->m_cWnd < tcb->m_ssThresh)
183 {
184 TcpNewReno::SlowStart(tcb, segmentsAcked);
185 NS_LOG_INFO("In SlowStart, updated to cwnd " << tcb->m_cWnd << " ssthresh "
186 << tcb->m_ssThresh);
187 }
188 else
189 {
190 uint32_t segCwnd = tcb->GetCwndInSegments();
191 uint32_t oldCwnd = segCwnd;
192
193 if (segmentsAcked > 0)
194 {
195 m_ackCnt += segmentsAcked * m_alpha;
196 }
197
198 while (m_ackCnt >= segCwnd)
199 {
200 m_ackCnt -= segCwnd;
201 segCwnd += 1;
202 }
203
204 if (segCwnd != oldCwnd)
205 {
206 tcb->m_cWnd = segCwnd * tcb->m_segmentSize;
207 NS_LOG_INFO("In CongAvoid, updated to cwnd " << tcb->m_cWnd << " ssthresh "
208 << tcb->m_ssThresh);
209 }
210 }
211}
212
213void
215{
216 NS_LOG_FUNCTION(this << tcb << packetsAcked << rtt);
217
218 if (rtt.IsZero())
219 {
220 return;
221 }
222
223 // Keep track of minimum RTT
224 m_baseRtt = std::min(m_baseRtt, rtt);
225
226 // Keep track of maximum RTT
227 m_maxRtt = std::max(rtt, m_maxRtt);
228
229 ++m_cntRtt;
230 m_sumRtt += rtt;
231
232 NS_LOG_INFO("Updated baseRtt = " << m_baseRtt << " maxRtt = " << m_maxRtt
233 << " cntRtt = " << m_cntRtt << " sumRtt = " << m_sumRtt);
234}
235
238{
239 NS_LOG_FUNCTION(this << tcb << bytesInFlight);
240
241 uint32_t segBytesInFlight = bytesInFlight / tcb->m_segmentSize;
242 uint32_t ssThresh = static_cast<uint32_t>(std::max(2.0, (1.0 - m_beta) * segBytesInFlight));
243
244 NS_LOG_DEBUG("Calculated ssThresh (in segments) = " << ssThresh);
245
246 return ssThresh * tcb->m_segmentSize;
247}
248
249void
250TcpIllinois::CalculateAlpha(double da, double dm)
251{
252 NS_LOG_FUNCTION(this << da << dm);
253
254 double d1 = dm / 100;
255
256 if (da <= d1)
257 {
258 NS_LOG_INFO("da <= d1");
259
260 if (!m_rttAbove)
261 { // In case we can't get out of this low delay zone, we use alphaMax
263 }
264 if (++m_rttLow >= m_theta)
265 {
266 /*
267 * da needs to stay below d1 for theta times RTT amount of time
268 * before we can increase alpha to alphaMax
269 */
270 NS_LOG_INFO("da stays below d1 for theta times RTT amount of time, "
271 "increase alpha to alphaMax");
272
273 m_rttLow = 0;
274 m_rttAbove = false;
276 }
277 }
278 else
279 {
280 NS_LOG_INFO("da > d1");
281
282 m_rttAbove = true;
283 /*
284 * alpha = k1 / (k2 + da), where
285 * k1 = ((dm - d1) * alphaMin * alphaMax) / (alphaMax - alphaMin)
286 * k2 = (((dm - d1) * alphaMin) / (alphaMax - alphaMin)) - d1
287 */
288 dm -= d1;
289 da -= d1;
290 m_alpha = (dm * m_alphaMax) / (dm + (da * (m_alphaMax - m_alphaMin)) / m_alphaMin);
291 }
292
293 NS_LOG_INFO("Updated to alpha = " << m_alpha);
294}
295
296void
297TcpIllinois::CalculateBeta(double da, double dm)
298{
299 NS_LOG_FUNCTION(this << da << dm);
300
301 double d2;
302 double d3;
303
304 d2 = dm / 10;
305 d3 = (8 * dm) / 10;
306
307 if (da <= d2)
308 {
309 NS_LOG_INFO("da <= d2");
310
312 }
313
314 else if (da > d2 && da < d3)
315 {
316 NS_LOG_INFO("da > d2 && da < d3");
317
318 /*
319 * beta = k3 + k4 * da, where
320 * k3 = (betaMin * d3 - betaMax * d2) / (d3 - d2)
321 * k4 = (betaMax - betaMin) / (d3 - d2)
322 */
323 m_beta = (m_betaMin * d3 - m_betaMax * d2 + (m_betaMax - m_betaMin) * da) / (d3 - d2);
324 }
325
326 else if (da >= d3 || d3 <= d2)
327 {
328 NS_LOG_INFO("da >= d3 || d3 <= d2");
329
331 }
332
333 NS_LOG_INFO("Updated to beta = " << m_beta);
334}
335
336Time
338{
339 NS_LOG_FUNCTION(this);
340
341 return (m_sumRtt / m_cntRtt - m_baseRtt);
342}
343
344Time
346{
347 NS_LOG_FUNCTION(this);
348
349 return (m_maxRtt - m_baseRtt);
350}
351
352void
354{
355 NS_LOG_FUNCTION(this << nextTxSequence);
356
357 m_endSeq = nextTxSequence;
358 m_cntRtt = 0;
359 m_sumRtt = Time(0);
360}
361
364{
365 NS_LOG_FUNCTION(this);
366
367 return CopyObject<TcpIllinois>(this);
368}
369
370std::string
372{
373 NS_LOG_FUNCTION(this);
374
375 return "TcpIllinois";
376}
377
378} // namespace ns3
#define Max(a, b)
#define Min(a, b)
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
friend Ptr< T > CopyObject(Ptr< T > object)
Copy an Object.
Definition object.h:581
Smart pointer class similar to boost::intrusive_ptr.
An implementation of TCP Illinois algorithm.
double m_alphaBase
Base value of alpha for standard AIMD.
double m_beta
Multiplicative decrease factor.
uint32_t m_ackCnt
Number of received ACK.
void RecalcParam(uint32_t cWnd)
Recalculate alpha and beta every RTT.
Time CalculateMaxDelay() const
Calculate maximum queueing delay.
uint32_t GetSsThresh(Ptr< const TcpSocketState > tcb, uint32_t bytesInFlight) override
Get slow start threshold after congestion event.
bool m_rttAbove
True when da > d1.
std::string GetName() const override
Get the name of the congestion control algorithm.
static TypeId GetTypeId()
Get the type ID.
double m_betaMin
Minimum beta threshold.
void CalculateAlpha(double da, double dm)
Calculate additive increase factor alpha.
void CongestionStateSet(Ptr< TcpSocketState > tcb, const TcpSocketState::TcpCongState_t newState) override
Reset Illinois parameters to default values upon a loss.
Time m_baseRtt
Minimum of all RTT measurements.
double m_alphaMin
Minimum alpha threshold.
uint32_t m_winThresh
Window threshold for adaptive sizing.
uint32_t m_cntRtt
Number of RTT measurements during last RTT.
TcpIllinois()
Create an unbound tcp socket.
void IncreaseWindow(Ptr< TcpSocketState > tcb, uint32_t segmentsAcked) override
Adjust cwnd following Illinois congestion avoidance algorithm.
uint8_t m_rttLow
Number of RTTs da has stayed below d1.
void CalculateBeta(double da, double dm)
Calculate multiplicative decrease factor beta.
Time m_maxRtt
Maximum of all RTT measurements.
double m_alpha
Additive increase factor.
double m_betaMax
Maximum beta threshold.
double m_betaBase
Base value of beta for standard AIMD.
uint32_t m_theta
Number of RTTs required before setting alpha to its max.
~TcpIllinois() override
Time m_sumRtt
Sum of all RTT measurements during last RTT.
double m_alphaMax
Maximum alpha threshold.
Ptr< TcpCongestionOps > Fork() override
Copy the congestion control algorithm across sockets.
void Reset(const SequenceNumber32 &nextTxSequence)
Reset Illinois parameters.
void PktsAcked(Ptr< TcpSocketState > tcb, uint32_t segmentsAcked, const Time &rtt) override
Measure RTT for each ACK Keep track of min and max RTT.
Time CalculateAvgDelay() const
Calculate average queueing delay.
SequenceNumber32 m_endSeq
Right edge of current RTT.
The NewReno implementation.
virtual uint32_t SlowStart(Ptr< TcpSocketState > tcb, uint32_t segmentsAcked)
Tcp NewReno slow start algorithm.
TcpCongState_t
Definition of the Congestion state machine.
@ CA_LOSS
CWND was reduced due to RTO timeout or SACK reneging.
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
int64_t GetMilliSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:397
bool IsZero() const
Exactly equivalent to t == 0.
Definition nstime.h:304
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Hold an unsigned integer type.
Definition uinteger.h:34
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition uinteger.h:35
Ptr< const AttributeChecker > MakeDoubleChecker()
Definition double.h:82
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition double.h:32