A Discrete-Event Network Simulator
API
tcp-veno-test.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2016 ResiliNets, ITTC, University of Kansas
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Truc Anh N. Nguyen <annguyen@ittc.ku.edu>
19 *
20 * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
21 * ResiliNets Research Group http://wiki.ittc.ku.edu/resilinets
22 * Information and Telecommunication Technology Center (ITTC)
23 * and Department of Electrical Engineering and Computer Science
24 * The University of Kansas Lawrence, KS USA.
25 */
26
27#include "ns3/test.h"
28#include "ns3/log.h"
29#include "ns3/tcp-congestion-ops.h"
30#include "ns3/tcp-socket-base.h"
31#include "ns3/tcp-veno.h"
32
33using namespace ns3;
34
35NS_LOG_COMPONENT_DEFINE ("TcpVenoTestSuite");
36
43class TcpVenoTest : public TestCase
44{
45public:
58 uint32_t ssThresh,
59 Time rtt,
60 uint32_t segmentsAcked,
61 uint32_t numRtt,
62 const std::string &name);
63
64private:
65 virtual void DoRun (void);
66
74
82 uint32_t MultiplicativeDecrease (uint32_t diff, const UintegerValue &beta, uint32_t bytesInFlight);
83
89 void NewReno_IncreaseWindow (Ptr<TcpSocketState> state, uint32_t segmentsAcked);
90
98
104 void NewReno_CongestionAvoidance (Ptr<TcpSocketState> state, uint32_t segmentsAcked);
105
106
113 bool m_inc;
115};
116
119 uint32_t ssThresh,
120 Time rtt,
121 uint32_t segmentsAcked,
122 uint32_t numRtt,
123 const std::string &name)
124 : TestCase (name),
125 m_cWnd (cWnd),
126 m_segmentSize (segmentSize),
127 m_ssThresh (ssThresh),
128 m_rtt (rtt),
129 m_segmentsAcked (segmentsAcked),
130 m_numRtt (numRtt),
131 m_inc (true)
132{
133}
134
135void
137{
138 m_state = CreateObject<TcpSocketState> ();
139
144
145 Ptr<TcpVeno> cong = CreateObject <TcpVeno> ();
146
147 // Set baseRtt to 100 ms
148 Time baseRtt = MilliSeconds (100);
149 cong->PktsAcked (m_state, m_segmentsAcked, baseRtt);
150
151 // Re-set Veno to assign a new value of minRtt
152 cong->CongestionStateSet (m_state, TcpSocketState::CA_OPEN);
153
154 uint32_t segCwnd = m_cWnd / m_segmentSize;
155
156 // Calculate expected throughput
157 uint32_t expectedCwnd;
158 double tmp = baseRtt.GetSeconds () / m_rtt.GetSeconds ();
159 expectedCwnd = segCwnd * tmp;
160
161 // Calculate the difference between actual and expected throughput
162 uint32_t diff;
163 diff = segCwnd - expectedCwnd;
164
165 // Get the beta attribute
166 UintegerValue beta;
167 cong->GetAttribute ("Beta", beta);
168
169 uint32_t cntRtt = 0;
170
171 TcpSocketState state;
172 state.m_cWnd = m_cWnd;
173 state.m_ssThresh = m_ssThresh;
175
176 while (m_numRtt != 0)
177 {
178 // Update cwnd using Veno's additive increase algorithm
179 cong->PktsAcked (m_state, m_segmentsAcked, m_rtt);
180 cong->IncreaseWindow (m_state, m_segmentsAcked);
181
182 // The first round the internal m_diff of cong will be 4, just like us
183 if (cntRtt == 0)
184 {
185 // Update ssthresh using Veno's multiplicative decrease algorithm
186 uint32_t ssThresh = cong->GetSsThresh (m_state, m_state->m_cWnd);
187
188 // Our calculation of ssthresh
189 uint32_t calculatedSsThresh = MultiplicativeDecrease (diff, beta, m_state->m_cWnd.Get ());
190
191 NS_TEST_ASSERT_MSG_EQ (ssThresh, calculatedSsThresh,
192 "Veno has not decremented cWnd correctly based on its"
193 "multiplicative decrease algo.");
194 }
195
196 // Our calculation of cwnd
197 if (cntRtt <= 2)
198 {
199 NewReno_IncreaseWindow (&state, 1);
200 }
201 else
202 {
203 AdditiveIncrease (&state, diff, beta);
204 }
205
207 "CWnd has not updated correctly based on Veno linear increase algorithm");
208 m_numRtt--;
209 cntRtt++;
210 }
211}
212
213void
215{
216 if (m_cWnd < m_ssThresh)
217 { // Slow start
218 NewReno_SlowStart (state, 1);
219 }
220 else
221 { // Congestion avoidance
222 if (diff < beta.Get ())
223 { // Increase cwnd by 1 every RTT when bandwidth is not fully utilized
225 }
226 else
227 { // Increase cwnd by 1 every other RTT when bandwidth is fully utilized
228 if (m_inc)
229 {
231 m_inc = false;
232 }
233 else
234 {
235 m_inc = true;
236 }
237 }
238 }
239}
240
243 uint32_t bytesInFlight)
244{
245 uint32_t calculatedSsThresh;
246 if (diff < beta.Get ())
247 {
248 static double tmp = 4.0 / 5.0;
249 calculatedSsThresh = std::max (2 * m_segmentSize, static_cast<uint32_t> (bytesInFlight * tmp));
250 }
251 else
252 {
253 calculatedSsThresh = std::max (2 * m_segmentSize, bytesInFlight / 2);
254 }
255 return calculatedSsThresh;
256}
257
258void
260{
261 if (state->m_cWnd < state->m_ssThresh)
262 {
263 segmentsAcked = NewReno_SlowStart (state, segmentsAcked);
264 }
265
266 if (state->m_cWnd >= state->m_ssThresh)
267 {
268 NewReno_CongestionAvoidance (state, segmentsAcked);
269 }
270}
271
274{
275 if (segmentsAcked >= 1)
276 {
277 state->m_cWnd += state->m_segmentSize;
278 return segmentsAcked - 1;
279 }
280
281 return 0;
282}
283
284void
286{
287 if (segmentsAcked > 0)
288 {
289 double adder = static_cast<double> (state->m_segmentSize * state->m_segmentSize) / state->m_cWnd.Get ();
290 adder = std::max (1.0, adder);
291 state->m_cWnd += static_cast<uint32_t> (adder);
292 }
293}
294
295
303{
304public:
305 TcpVenoTestSuite () : TestSuite ("tcp-veno-test", UNIT)
306 {
307 AddTestCase (new TcpVenoTest (38 * 1446, 1446, 40 * 1446, MilliSeconds (100), 1, 1,
308 "Veno test on cWnd in slow start and non-congestive loss"),
309 TestCase::QUICK);
310 AddTestCase (new TcpVenoTest (30 * 536, 536, 20 * 536, MilliSeconds (106), 1, 1,
311 "Veno test on cWnd with diff < beta"),
312 TestCase::QUICK);
313 AddTestCase (new TcpVenoTest (60 * 536, 536, 40 * 536, MilliSeconds (106), 1, 3,
314 "Veno increment test on cWnd with diff > beta"),
315 TestCase::QUICK);
316 }
317};
318
320
321
#define max(a, b)
Definition: 80211b.c:43
Testing the additive increase and multiplicative decrease of TcpVeno.
void NewReno_CongestionAvoidance(Ptr< TcpSocketState > state, uint32_t segmentsAcked)
Mimics the NewReno Congestion Avoidance algorithm.
Time m_rtt
RTT.
uint32_t m_numRtt
Number of RTT (i.e., rounds) of the test.
bool m_inc
Internal flag to increase every other round.
uint32_t MultiplicativeDecrease(uint32_t diff, const UintegerValue &beta, uint32_t bytesInFlight)
TCP Veno multiplicative decrease formula.
uint32_t m_segmentsAcked
Number of segments ACKed.
uint32_t NewReno_SlowStart(Ptr< TcpSocketState > state, uint32_t segmentsAcked)
Mimics the NewReno SlowStart algorithm.
uint32_t m_cWnd
Congestion window.
TcpVenoTest(uint32_t cWnd, uint32_t segmentSize, uint32_t ssThresh, Time rtt, uint32_t segmentsAcked, uint32_t numRtt, const std::string &name)
Constructor.
uint32_t m_ssThresh
Slow Start Threshold.
Ptr< TcpSocketState > m_state
TCP socket state.
uint32_t m_segmentSize
Segment size.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void NewReno_IncreaseWindow(Ptr< TcpSocketState > state, uint32_t segmentsAcked)
Mimics the NewReno IncreaseWindow algorithm.
void AdditiveIncrease(Ptr< TcpSocketState > state, uint32_t diff, UintegerValue beta)
TCP Veno additive increase formula.
TCP Veno TestSuite.
Data structure that records the congestion state of a connection.
uint32_t m_segmentSize
Segment size.
Time m_minRtt
Minimum RTT observed throughout the connection.
TracedValue< uint32_t > m_cWnd
Congestion window.
TracedValue< uint32_t > m_ssThresh
Slow start threshold.
encapsulates test code
Definition: test.h:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
@ UNIT
This test suite implements a Unit Test.
Definition: test.h:1197
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:379
T Get(void) const
Get the underlying value.
Definition: traced-value.h:232
Hold an unsigned integer type.
Definition: uinteger.h:44
uint64_t Get(void) const
Definition: uinteger.cc:35
uint32_t segmentSize
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#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:141
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1252
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static TcpVenoTestSuite g_tcpVenoTest
Static variable for test initialization.