A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tcp-illinois-test.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: Truc Anh N. Nguyen <annguyen@ittc.ku.edu>
7 *
8 * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
9 * ResiliNets Research Group https://resilinets.org/
10 * Information and Telecommunication Technology Center (ITTC)
11 * and Department of Electrical Engineering and Computer Science
12 * The University of Kansas Lawrence, KS USA.
13 */
14
15#include "ns3/log.h"
16#include "ns3/tcp-congestion-ops.h"
17#include "ns3/tcp-illinois.h"
18#include "ns3/tcp-socket-base.h"
19#include "ns3/test.h"
20
21using namespace ns3;
22
23NS_LOG_COMPONENT_DEFINE("TcpIllinoisTestSuite");
24
25/**
26 * \ingroup internet-test
27 *
28 * \brief TcpIllinois C-AIMD algorithm tests.
29 */
31{
32 public:
33 /**
34 * \brief Constructor.
35 * \param cWnd Congestion window.
36 * \param ssThresh Slow Start Threshold.
37 * \param segmentSize Segment size.
38 * \param cntRtt RTT counter.
39 * \param maxRtt Max RTT.
40 * \param segmentsAcked Number of segments ACKed.
41 * \param nextTxSeq Next Tx sequence number.
42 * \param lastAckedSeq Last ACKed sequence number.
43 * \param name Test description.
44 */
46 uint32_t ssThresh,
48 uint32_t cntRtt,
49 Time maxRtt,
50 uint32_t segmentsAcked,
51 SequenceNumber32 nextTxSeq,
52 SequenceNumber32 lastAckedSeq,
53 const std::string& name);
54
55 private:
56 void DoRun() override;
57 /**
58 * \brief Increases the TCP window.
59 * \param cong The congestion control.
60 */
62 /**
63 * \brief Recalculate the internal TCP Illinois params.
64 * \param cong The congestion control.
65 */
67 /**
68 * \brief Calculate the maximum delay.
69 * \returns The maximum delay.
70 */
72 /**
73 * \brief Calculate the average delay.
74 * \returns The average delay.
75 */
77 /**
78 * \brief Calculate the TCP Illinois alpha param.
79 * \param cong The congestion control.
80 * \param da Average delay (in milliseconds).
81 * \param dm Maximum delay (in milliseconds).
82 */
83 void CalculateAlpha(Ptr<TcpIllinois> cong, double da, double dm);
84 /**
85 * \brief Calculate the TCP Illinois beta param.
86 * \param cong The congestion control.
87 * \param da Average delay (in milliseconds).
88 * \param dm Maximum delay (in milliseconds).
89 */
90 void CalculateBeta(Ptr<TcpIllinois> cong, double da, double dm);
91 /**
92 * brief Get and check the SSH threshold.
93 */
94 void GetSsThresh();
95
96 uint32_t m_cWnd; //!< Congestion window.
97 uint32_t m_ssThresh; //!< Slow Start Threshold.
98 uint32_t m_segmentSize; //!< Segment size.
99 Time m_baseRtt; //!< Base RTT.
100 Time m_maxRtt; //!< Max RTT.
101 uint32_t m_segmentsAcked; //!< Number of segments ACKed.
102 SequenceNumber32 m_nextTxSeq; //!< Next Tx sequence number.
103 SequenceNumber32 m_lastAckedSeq; //!< Last ACKed sequence number.
104 double m_alpha; //!< TCP Illinois alpha parameter.
105 double m_beta; //!< TCP Illinois beta parameter.
106 uint32_t m_cntRtt; //!< RTT counter.
107 Time m_sumRtt; //!< Sum of all the RTTs.
108 bool m_rttAbove; //!< RTT above threshold.
109 uint8_t m_rttLow; //!< RTT low counter.
110 uint32_t m_ackCnt; //!< ACK counter.
111};
112
114 uint32_t ssThresh,
116 uint32_t cntRtt,
117 Time maxRtt,
118 uint32_t segmentsAcked,
119 SequenceNumber32 nextTxSeq,
120 SequenceNumber32 lastAckedSeq,
121 const std::string& name)
122 : TestCase(name),
123 m_cWnd(cWnd),
124 m_ssThresh(ssThresh),
125 m_segmentSize(segmentSize),
126 m_baseRtt(MilliSeconds(100)),
127 m_maxRtt(maxRtt),
128 m_segmentsAcked(segmentsAcked),
129 m_nextTxSeq(nextTxSeq),
130 m_lastAckedSeq(lastAckedSeq),
131 m_alpha(0.0),
132 m_beta(0.0),
133 m_cntRtt(cntRtt),
134 m_sumRtt(0),
135 m_rttAbove(false),
136 m_rttLow(0),
137 m_ackCnt(0)
138{
139}
140
141void
143{
145 state->m_cWnd = m_cWnd;
146 state->m_ssThresh = m_ssThresh;
147 state->m_segmentSize = m_segmentSize;
148 state->m_nextTxSequence = m_nextTxSeq;
149 state->m_lastAckedSeq = m_lastAckedSeq;
150
152
153 // Set baseRtt to 100 ms
154 cong->PktsAcked(state, m_segmentsAcked, m_baseRtt);
155
157
158 // Set maxRtt and update sumRtt based on cntRtt value
159 for (uint32_t count = 1; count < m_cntRtt; ++count)
160 {
161 cong->PktsAcked(state, m_segmentsAcked, m_maxRtt);
163 }
164
165 /*
166 * Test cWnd modification during additive increase
167 */
168 cong->IncreaseWindow(state, m_segmentsAcked);
169 IncreaseWindow(cong);
170 NS_TEST_ASSERT_MSG_EQ(state->m_cWnd.Get(), m_cWnd, "CWnd has not updated correctly");
171
172 /*
173 * Test ssThresh modification during multiplicative decrease
174 */
175 uint32_t ssThresh = cong->GetSsThresh(state, m_cWnd);
176 GetSsThresh();
177 NS_TEST_ASSERT_MSG_EQ(ssThresh, m_ssThresh, "SsThresh has not updated correctly");
178}
179
180void
182{
183 uint32_t segCwnd = m_cWnd / m_segmentSize;
184
186 {
187 RecalcParam(cong);
188 }
189 if (m_cWnd < m_ssThresh)
190 { // NewReno slow start
191 if (m_segmentsAcked >= 1)
192 {
194 m_segmentsAcked -= 1;
195 }
196 NS_LOG_INFO("In SlowStart, updated to cwnd " << m_cWnd << " ssthresh " << m_ssThresh);
197 }
198 else
199 {
200 uint32_t oldCwnd = segCwnd;
201
202 if (m_segmentsAcked > 0)
203 {
205 }
206
207 while (m_ackCnt >= segCwnd)
208 {
209 m_ackCnt -= segCwnd;
210 segCwnd += 1;
211 }
212
213 if (segCwnd != oldCwnd)
214 {
215 m_cWnd = segCwnd * m_segmentSize;
216 NS_LOG_INFO("In CongAvoid, updated to cwnd " << m_cWnd << " ssthresh " << m_ssThresh);
217 }
218 }
219}
220
221void
223{
224 DoubleValue alphaBase;
225 cong->GetAttribute("AlphaBase", alphaBase);
226 UintegerValue winThresh;
227 cong->GetAttribute("WinThresh", winThresh);
228
229 if (m_cWnd < winThresh.Get())
230 {
231 NS_LOG_INFO("cWnd < winThresh, set alpha & beta to base values");
232 m_alpha = alphaBase.Get();
233 }
234 else if (m_cntRtt > 0)
235 {
238
239 NS_LOG_INFO("Updated to dm = " << dm << " da = " << da);
240
241 CalculateAlpha(cong, da, dm);
242 CalculateBeta(cong, da, dm);
243 }
244}
245
246Time
251
252Time
257
258void
260{
261 DoubleValue alphaMax;
262 cong->GetAttribute("AlphaMax", alphaMax);
263 UintegerValue theta;
264 cong->GetAttribute("Theta", theta);
265 DoubleValue alphaMin;
266 cong->GetAttribute("AlphaMin", alphaMin);
267
268 double d1 = dm / 100;
269
270 if (da <= d1)
271 {
272 if (!m_rttAbove)
273 {
274 m_alpha = alphaMax.Get();
275 }
276 if (++m_rttLow >= theta.Get())
277 {
278 m_rttLow = 0;
279 m_rttAbove = false;
280 m_alpha = alphaMax.Get();
281 }
282 }
283 else
284 {
285 m_rttAbove = true;
286 dm -= d1;
287 da -= d1;
288 m_alpha = (dm * alphaMax.Get()) /
289 (dm + (da * (alphaMax.Get() - alphaMin.Get())) / alphaMin.Get());
290 }
291 NS_LOG_INFO("Updated to alpha = " << m_alpha);
292}
293
294void
296{
297 DoubleValue betaMin;
298 cong->GetAttribute("BetaMin", betaMin);
299 DoubleValue betaMax;
300 cong->GetAttribute("BetaMax", betaMax);
301
302 double d2;
303 double d3;
304 d2 = dm / 10;
305 d3 = (8 * dm) / 10;
306
307 if (da <= d2)
308 {
309 m_beta = betaMin.Get();
310 }
311 else if (da > d2 && da < d3)
312 {
313 m_beta = (betaMin.Get() * d3 - betaMax.Get() * d2 + (betaMax.Get() - betaMin.Get()) * da) /
314 (d3 - d2);
315 }
316
317 else if (da >= d3 || d3 <= d2)
318 {
319 m_beta = betaMax.Get();
320 }
321 NS_LOG_INFO("Updated to beta = " << m_beta);
322}
323
324void
326{
327 uint32_t segCwnd = m_cWnd / m_segmentSize;
328 uint32_t ssThresh = std::max(2.0, (1.0 - m_beta) * segCwnd);
329
330 NS_LOG_DEBUG("Calculated ssThresh (in segments) = " << ssThresh);
331
332 m_ssThresh = ssThresh * m_segmentSize;
333}
334
335/**
336 * \ingroup internet-test
337 *
338 * \brief TCP Illinois TestSuite
339 */
341{
342 public:
344 : TestSuite("tcp-illinois-test", Type::UNIT)
345 {
346 AddTestCase(new TcpIllinoisTest(38 * 1446,
347 40 * 1446,
348 1446,
349 2,
350 MilliSeconds(105),
351 2,
352 SequenceNumber32(2893),
353 SequenceNumber32(5785),
354 "Illinois test on cWnd and ssThresh when in slow start"),
355 TestCase::Duration::QUICK);
357 60 * 346,
358 40 * 346,
359 346,
360 2,
361 MilliSeconds(100),
362 2,
363 SequenceNumber32(2893),
364 SequenceNumber32(5785),
365 "Illinois test on cWnd and ssThresh when avg queueing delay is at minimum"),
366 TestCase::Duration::QUICK);
368 38 * 1446,
369 40 * 1446,
370 1446,
371 5,
372 MilliSeconds(110),
373 2,
374 SequenceNumber32(2893),
375 SequenceNumber32(5785),
376 "Illinois test on cWnd and ssThresh when avg queueing delay is at maximum"),
377 TestCase::Duration::QUICK);
378 AddTestCase(new TcpIllinoisTest(40 * 1446,
379 38 * 1446,
380 1446,
381 2,
382 MilliSeconds(105),
383 55,
384 SequenceNumber32(2893),
385 SequenceNumber32(5785),
386 "Illinois test on cWnd and ssThresh when avg queueing "
387 "delay is in between its min & max"),
388 TestCase::Duration::QUICK);
389 }
390};
391
392static TcpIllinoisTestSuite g_tcpIllinoisTest; //!< Static variable for test initialization
TcpIllinois C-AIMD algorithm tests.
Time CalculateAvgDelay()
Calculate the average delay.
Time CalculateMaxDelay()
Calculate the maximum delay.
void CalculateAlpha(Ptr< TcpIllinois > cong, double da, double dm)
Calculate the TCP Illinois alpha param.
SequenceNumber32 m_lastAckedSeq
Last ACKed sequence number.
void RecalcParam(Ptr< TcpIllinois > cong)
Recalculate the internal TCP Illinois params.
Time m_baseRtt
Base RTT.
uint32_t m_ackCnt
ACK counter.
void IncreaseWindow(Ptr< TcpIllinois > cong)
Increases the TCP window.
SequenceNumber32 m_nextTxSeq
Next Tx sequence number.
uint8_t m_rttLow
RTT low counter.
TcpIllinoisTest(uint32_t cWnd, uint32_t ssThresh, uint32_t segmentSize, uint32_t cntRtt, Time maxRtt, uint32_t segmentsAcked, SequenceNumber32 nextTxSeq, SequenceNumber32 lastAckedSeq, const std::string &name)
Constructor.
uint32_t m_cntRtt
RTT counter.
uint32_t m_cWnd
Congestion window.
bool m_rttAbove
RTT above threshold.
void CalculateBeta(Ptr< TcpIllinois > cong, double da, double dm)
Calculate the TCP Illinois beta param.
Time m_sumRtt
Sum of all the RTTs.
void GetSsThresh()
brief Get and check the SSH threshold.
void DoRun() override
Implementation to actually run this TestCase.
double m_alpha
TCP Illinois alpha parameter.
uint32_t m_ssThresh
Slow Start Threshold.
double m_beta
TCP Illinois beta parameter.
uint32_t m_segmentSize
Segment size.
uint32_t m_segmentsAcked
Number of segments ACKed.
TCP Illinois TestSuite.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
double Get() const
Definition double.cc:26
Smart pointer class similar to boost::intrusive_ptr.
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
static constexpr auto UNIT
Definition test.h:1291
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
Hold an unsigned integer type.
Definition uinteger.h:34
uint64_t Get() const
Definition uinteger.cc:26
uint32_t segmentSize
#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_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
SequenceNumber< uint32_t, int32_t > SequenceNumber32
32 bit Sequence number.
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition test.h:134
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1320
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static TcpIllinoisTestSuite g_tcpIllinoisTest
Static variable for test initialization.