A Discrete-Event Network Simulator
API
tcp-illinois-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2016 ResiliNets, ITTC, University of Kansas
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Truc Anh N. Nguyen <annguyen@ittc.ku.edu>
18 *
19 * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
20 * ResiliNets Research Group https://resilinets.org/
21 * Information and Telecommunication Technology Center (ITTC)
22 * and Department of Electrical Engineering and Computer Science
23 * The University of Kansas Lawrence, KS USA.
24 */
25
26#include "ns3/log.h"
27#include "ns3/tcp-congestion-ops.h"
28#include "ns3/tcp-illinois.h"
29#include "ns3/tcp-socket-base.h"
30#include "ns3/test.h"
31
32using namespace ns3;
33
34NS_LOG_COMPONENT_DEFINE("TcpIllinoisTestSuite");
35
43{
44 public:
58 uint32_t ssThresh,
60 uint32_t cntRtt,
61 Time maxRtt,
62 uint32_t segmentsAcked,
63 SequenceNumber32 nextTxSeq,
64 SequenceNumber32 lastAckedSeq,
65 const std::string& name);
66
67 private:
68 void DoRun() override;
95 void CalculateAlpha(Ptr<TcpIllinois> cong, double da, double dm);
102 void CalculateBeta(Ptr<TcpIllinois> cong, double da, double dm);
106 void GetSsThresh();
107
116 double m_alpha;
117 double m_beta;
121 uint8_t m_rttLow;
123};
124
126 uint32_t ssThresh,
128 uint32_t cntRtt,
129 Time maxRtt,
130 uint32_t segmentsAcked,
131 SequenceNumber32 nextTxSeq,
132 SequenceNumber32 lastAckedSeq,
133 const std::string& name)
134 : TestCase(name),
135 m_cWnd(cWnd),
136 m_ssThresh(ssThresh),
137 m_segmentSize(segmentSize),
138 m_baseRtt(MilliSeconds(100)),
139 m_maxRtt(maxRtt),
140 m_segmentsAcked(segmentsAcked),
141 m_nextTxSeq(nextTxSeq),
142 m_lastAckedSeq(lastAckedSeq),
143 m_alpha(0.0),
144 m_beta(0.0),
145 m_cntRtt(cntRtt),
146 m_sumRtt(0),
147 m_rttAbove(false),
148 m_rttLow(0),
149 m_ackCnt(0)
150{
151}
152
153void
155{
156 Ptr<TcpSocketState> state = CreateObject<TcpSocketState>();
157 state->m_cWnd = m_cWnd;
158 state->m_ssThresh = m_ssThresh;
162
163 Ptr<TcpIllinois> cong = CreateObject<TcpIllinois>();
164
165 // Set baseRtt to 100 ms
166 cong->PktsAcked(state, m_segmentsAcked, m_baseRtt);
167
169
170 // Set maxRtt and update sumRtt based on cntRtt value
171 for (uint32_t count = 1; count < m_cntRtt; ++count)
172 {
173 cong->PktsAcked(state, m_segmentsAcked, m_maxRtt);
175 }
176
177 /*
178 * Test cWnd modification during additive increase
179 */
180 cong->IncreaseWindow(state, m_segmentsAcked);
181 IncreaseWindow(cong);
182 NS_TEST_ASSERT_MSG_EQ(state->m_cWnd.Get(), m_cWnd, "CWnd has not updated correctly");
183
184 /*
185 * Test ssThresh modification during multiplicative decrease
186 */
187 uint32_t ssThresh = cong->GetSsThresh(state, m_cWnd);
188 GetSsThresh();
189 NS_TEST_ASSERT_MSG_EQ(ssThresh, m_ssThresh, "SsThresh has not updated correctly");
190}
191
192void
194{
195 uint32_t segCwnd = m_cWnd / m_segmentSize;
196
198 {
199 RecalcParam(cong);
200 }
201 if (m_cWnd < m_ssThresh)
202 { // NewReno slow start
203 if (m_segmentsAcked >= 1)
204 {
206 m_segmentsAcked -= 1;
207 }
208 NS_LOG_INFO("In SlowStart, updated to cwnd " << m_cWnd << " ssthresh " << m_ssThresh);
209 }
210 else
211 {
212 uint32_t oldCwnd = segCwnd;
213
214 if (m_segmentsAcked > 0)
215 {
217 }
218
219 while (m_ackCnt >= segCwnd)
220 {
221 m_ackCnt -= segCwnd;
222 segCwnd += 1;
223 }
224
225 if (segCwnd != oldCwnd)
226 {
227 m_cWnd = segCwnd * m_segmentSize;
228 NS_LOG_INFO("In CongAvoid, updated to cwnd " << m_cWnd << " ssthresh " << m_ssThresh);
229 }
230 }
231}
232
233void
235{
236 DoubleValue alphaBase;
237 cong->GetAttribute("AlphaBase", alphaBase);
238 UintegerValue winThresh;
239 cong->GetAttribute("WinThresh", winThresh);
240
241 if (m_cWnd < winThresh.Get())
242 {
243 NS_LOG_INFO("cWnd < winThresh, set alpha & beta to base values");
244 m_alpha = alphaBase.Get();
245 }
246 else if (m_cntRtt > 0)
247 {
250
251 NS_LOG_INFO("Updated to dm = " << dm << " da = " << da);
252
253 CalculateAlpha(cong, da, dm);
254 CalculateBeta(cong, da, dm);
255 }
256}
257
258Time
260{
261 return (m_maxRtt - m_baseRtt);
262}
263
264Time
266{
267 return (m_sumRtt / m_cntRtt - m_baseRtt);
268}
269
270void
272{
273 DoubleValue alphaMax;
274 cong->GetAttribute("AlphaMax", alphaMax);
275 UintegerValue theta;
276 cong->GetAttribute("Theta", theta);
277 DoubleValue alphaMin;
278 cong->GetAttribute("AlphaMin", alphaMin);
279
280 double d1 = dm / 100;
281
282 if (da <= d1)
283 {
284 if (!m_rttAbove)
285 {
286 m_alpha = alphaMax.Get();
287 }
288 if (++m_rttLow >= theta.Get())
289 {
290 m_rttLow = 0;
291 m_rttAbove = false;
292 m_alpha = alphaMax.Get();
293 }
294 }
295 else
296 {
297 m_rttAbove = true;
298 dm -= d1;
299 da -= d1;
300 m_alpha = (dm * alphaMax.Get()) /
301 (dm + (da * (alphaMax.Get() - alphaMin.Get())) / alphaMin.Get());
302 }
303 NS_LOG_INFO("Updated to alpha = " << m_alpha);
304}
305
306void
308{
309 DoubleValue betaMin;
310 cong->GetAttribute("BetaMin", betaMin);
311 DoubleValue betaMax;
312 cong->GetAttribute("BetaMax", betaMax);
313
314 double d2;
315 double d3;
316 d2 = dm / 10;
317 d3 = (8 * dm) / 10;
318
319 if (da <= d2)
320 {
321 m_beta = betaMin.Get();
322 }
323 else if (da > d2 && da < d3)
324 {
325 m_beta = (betaMin.Get() * d3 - betaMax.Get() * d2 + (betaMax.Get() - betaMin.Get()) * da) /
326 (d3 - d2);
327 }
328
329 else if (da >= d3 || d3 <= d2)
330 {
331 m_beta = betaMax.Get();
332 }
333 NS_LOG_INFO("Updated to beta = " << m_beta);
334}
335
336void
338{
339 uint32_t segCwnd = m_cWnd / m_segmentSize;
340 uint32_t ssThresh = std::max(2.0, (1.0 - m_beta) * segCwnd);
341
342 NS_LOG_DEBUG("Calculated ssThresh (in segments) = " << ssThresh);
343
344 m_ssThresh = ssThresh * m_segmentSize;
345}
346
354{
355 public:
357 : TestSuite("tcp-illinois-test", UNIT)
358 {
359 AddTestCase(new TcpIllinoisTest(38 * 1446,
360 40 * 1446,
361 1446,
362 2,
363 MilliSeconds(105),
364 2,
365 SequenceNumber32(2893),
366 SequenceNumber32(5785),
367 "Illinois test on cWnd and ssThresh when in slow start"),
368 TestCase::QUICK);
370 60 * 346,
371 40 * 346,
372 346,
373 2,
374 MilliSeconds(100),
375 2,
376 SequenceNumber32(2893),
377 SequenceNumber32(5785),
378 "Illinois test on cWnd and ssThresh when avg queueing delay is at minimum"),
379 TestCase::QUICK);
381 38 * 1446,
382 40 * 1446,
383 1446,
384 5,
385 MilliSeconds(110),
386 2,
387 SequenceNumber32(2893),
388 SequenceNumber32(5785),
389 "Illinois test on cWnd and ssThresh when avg queueing delay is at maximum"),
390 TestCase::QUICK);
391 AddTestCase(new TcpIllinoisTest(40 * 1446,
392 38 * 1446,
393 1446,
394 2,
395 MilliSeconds(105),
396 55,
397 SequenceNumber32(2893),
398 SequenceNumber32(5785),
399 "Illinois test on cWnd and ssThresh when avg queueing "
400 "delay is in between its min & max"),
401 TestCase::QUICK);
402 }
403};
404
#define max(a, b)
Definition: 80211b.c:43
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.
Time m_maxRtt
Max RTT.
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:42
double Get() const
Definition: double.cc:37
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
uint32_t m_segmentSize
Segment size.
SequenceNumber32 m_lastAckedSeq
Last sequence ACKed.
TracedValue< uint32_t > m_cWnd
Congestion window.
TracedValue< SequenceNumber32 > m_nextTxSequence
Next seqnum to be sent (SND.NXT), ReTx pushes it back.
TracedValue< uint32_t > m_ssThresh
Slow start threshold.
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:305
A suite of tests to run.
Definition: test.h:1256
@ UNIT
This test suite implements a Unit Test.
Definition: test.h:1265
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
int64_t GetMilliSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:407
T Get() const
Get the underlying value.
Definition: traced-value.h:249
Hold an unsigned integer type.
Definition: uinteger.h:45
uint64_t Get() const
Definition: uinteger.cc:37
uint32_t segmentSize
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
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:144
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1350
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static TcpIllinoisTestSuite g_tcpIllinoisTest
Static variable for test initialization.