A Discrete-Event Network Simulator
API
tcp-validation.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2019 Cable Television Laboratories, Inc.
4  * Copyright (c) 2020 Tom Henderson (adapted for DCTCP testing)
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions, and the following disclaimer,
11  * without modification.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  * 3. The names of the authors may not be used to endorse or promote products
16  * derived from this software without specific prior written permission.
17  *
18  * Alternatively, provided that this notice is retained in full, this
19  * software may be distributed under the terms of the GNU General
20  * Public License ("GPL") version 2, in which case the provisions of the
21  * GPL apply INSTEAD OF those given above.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 // This program is designed to observe long-running TCP congestion control
37 // behavior over a configurable bottleneck link. The program is also
38 // instrumented to check progam data against validated results, when
39 // the validation option is enabled.
40 //
41 // ---> downstream (primary data transfer from servers to clients)
42 // <--- upstream (return acks and ICMP echo response)
43 //
44 // ---- bottleneck link ----
45 // servers ---| WR |--------------------| LR |--- clients
46 // ---- ----
47 // ns-3 node IDs:
48 // nodes 0-2 3 4 5-7
49 //
50 // - The box WR is notionally a WAN router, aggregating all server links
51 // - The box LR is notionally a LAN router, aggregating all client links
52 // - Three servers are connected to WR, three clients are connected to LR
53 //
54 // clients and servers are configured for ICMP measurements and TCP throughput
55 // and latency measurements in the downstream direction
56 //
57 // All link rates are enforced by a point-to-point (P2P) ns-3 model with full
58 // duplex operation. Dynamic queue limits
59 // (BQL) are enabled to allow for queueing to occur at the priority queue layer;
60 // the notional P2P hardware device queue is limited to three packets.
61 //
62 // One-way link delays and link rates
63 // -----------------------------------
64 // (1) server to WR links, 1000 Mbps, 1us delay
65 // (2) bottleneck link: configurable rate, configurable delay
66 // (3) client to LR links, 1000 Mbps, 1us delay
67 //
68 // By default, ns-3 FQ-CoDel model is installed on all interfaces, but
69 // the bottleneck queue uses CoDel by default and is configurable.
70 //
71 // The ns-3 FQ-CoDel model uses ns-3 defaults:
72 // - 100ms interval
73 // - 5ms target
74 // - drop batch size of 64 packets
75 // - minbytes of 1500
76 //
77 // Default simulation time is 70 sec. For single flow experiments, the flow is
78 // started at simulation time 5 sec; if a second flow is used, it starts
79 // at 15 sec.
80 //
81 // ping frequency is set at 100ms.
82 //
83 // A command-line option to enable a step-threshold CE threshold
84 // from the CoDel queue model is provided.
85 //
86 // Measure:
87 // - ping RTT
88 // - TCP RTT estimate
89 // - TCP throughput
90 //
91 // IPv4 addressing
92 // ----------------------------
93 // pingServer 10.1.1.2 (ping source)
94 // firstServer 10.1.2.2 (data sender)
95 // secondServer 10.1.3.2 (data sender)
96 // pingClient 192.168.1.2
97 // firstClient 192.168.2.2
98 // secondClient 192.168.3.2
99 //
100 // Program Options:
101 // ---------------
102 // --firstTcpType: first TCP type (cubic, dctcp, or reno) [cubic]
103 // --secondTcpType: second TCP type (cubic, dctcp, or reno) []
104 // --queueType: bottleneck queue type (fq, codel, pie, or red) [codel]
105 // --baseRtt: base RTT [+80ms]
106 // --ceThreshold: CoDel CE threshold (for DCTCP) [+1ms]
107 // --linkRate: data rate of bottleneck link [50000000bps]
108 // --stopTime: simulation stop time [+1.16667min]
109 // --queueUseEcn: use ECN on queue [false]
110 // --enablePcap: enable Pcap [false]
111 // --validate: validation case to run []
112 //
113 // validation cases (and syntax of how to run):
114 // ------------
115 // Case 'dctcp-10ms': DCTCP single flow, 10ms base RTT, 50 Mbps link, ECN enabled, CoDel:
116 // ./waf --run 'tcp-validation --firstTcpType=dctcp --linkRate=50Mbps --baseRtt=10ms --queueUseEcn=1 --stopTime=15s --validate=1 --validation=dctcp-10ms'
117 // - Throughput between 48 Mbps and 49 Mbps for time greater than 5.6s
118 // - DCTCP alpha below 0.1 for time greater than 5.4s
119 // - DCTCP alpha between 0.06 and 0.085 for time greater than 7s
120 //
121 // Case 'dctcp-80ms': DCTCP single flow, 80ms base RTT, 50 Mbps link, ECN enabled, CoDel:
122 // ./waf --run 'tcp-validation --firstTcpType=dctcp --linkRate=50Mbps --baseRtt=80ms --queueUseEcn=1 --stopTime=40s --validate=1 --validation=dctcp-80ms'
123 // - Throughput less than 20 Mbps for time less than 14s
124 // - Throughput less than 48 Mbps for time less than 30s
125 // - Throughput between 47.5 Mbps and 48.5 for time greater than 32s
126 // - DCTCP alpha above 0.1 for time less than 7.5
127 // - DCTCP alpha below 0.01 for time greater than 11 and less than 30
128 // - DCTCP alpha between 0.015 and 0.025 for time greater than 34
129 //
130 // Case 'cubic-50ms-no-ecn': CUBIC single flow, 50ms base RTT, 50 Mbps link, ECN disabled, CoDel:
131 // ./waf --run 'tcp-validation --firstTcpType=cubic --linkRate=50Mbps --baseRtt=50ms --queueUseEcn=0 --stopTime=20s --validate=1 --validation=cubic-50ms-no-ecn'
132 // - Maximum value of cwnd is 511 segments at 5.4593 seconds
133 // - cwnd decreases to 173 segments at 5.80304 seconds
134 // - cwnd reaches another local maxima around 14.2815 seconds of 236 segments
135 // - cwnd reaches a second maximum around 18.048 seconds of 234 segments
136 //
137 // Case 'cubic-50ms-ecn': CUBIC single flow, 50ms base RTT, 50 Mbps link, ECN enabled, CoDel:
138 // ./waf --run 'tcp-validation --firstTcpType=cubic --linkRate=50Mbps --baseRtt=50ms --queueUseEcn=0 --stopTime=20s --validate=1 --validation=cubic-50ms-no-ecn'
139 // - Maximum value of cwnd is 511 segments at 5.4593 seconds
140 // - cwnd decreases to 173 segments at 5.7939 seconds
141 // - cwnd reaches another local maxima around 14.3477 seconds of 236 segments
142 // - cwnd reaches a second maximum around 18.064 seconds of 234 segments
143 
144 #include <iostream>
145 #include <fstream>
146 #include <string>
147 #include "ns3/core-module.h"
148 #include "ns3/network-module.h"
149 #include "ns3/applications-module.h"
150 #include "ns3/traffic-control-module.h"
151 #include "ns3/internet-module.h"
152 #include "ns3/internet-apps-module.h"
153 #include "ns3/point-to-point-module.h"
154 
155 using namespace ns3;
156 
157 NS_LOG_COMPONENT_DEFINE ("TcpValidation");
158 
159 // These variables are declared outside of main() so that they can
160 // be used in trace sinks.
161 uint32_t g_firstBytesReceived = 0;
163 uint32_t g_marksObserved = 0;
164 uint32_t g_dropsObserved = 0;
165 std::string g_validate = ""; // Empty string disables this mode
166 bool g_validationFailed = false;
167 
168 void
169 TraceFirstCwnd (std::ofstream* ofStream, uint32_t oldCwnd, uint32_t newCwnd)
170 {
171  // TCP segment size is configured below to be 1448 bytes
172  // so that we can report cwnd in units of segments
173  if (g_validate == "")
174  {
175  *ofStream << Simulator::Now ().GetSeconds () << " " << static_cast<double> (newCwnd) / 1448 << std::endl;
176  }
177  // Validation checks; both the ECN enabled and disabled cases are similar
178  if (g_validate == "cubic-50ms-no-ecn" || g_validate == "cubic-50ms-ecn")
179  {
180  double now = Simulator::Now ().GetSeconds ();
181  double cwnd = static_cast<double> (newCwnd) / 1448;
182  if ((now > 5.43) && (now < 5.465) && (cwnd < 500))
183  {
184  NS_LOG_WARN ("now " << Now ().As (Time::S) << " cwnd " << cwnd << " (expected >= 500)");
185  g_validationFailed = true;
186  }
187  else if ((now > 5.795) && (now < 6) && (cwnd > 190))
188  {
189  NS_LOG_WARN ("now " << Now ().As (Time::S) << " cwnd " << cwnd << " (expected <= 190)");
190  g_validationFailed = true;
191  }
192  else if ((now > 14) && (now < 14.197) && (cwnd < 224))
193  {
194  NS_LOG_WARN ("now " << Now ().As (Time::S) << " cwnd " << cwnd << " (expected >= 224)");
195  g_validationFailed = true;
196  }
197  else if ((now > 17) && (now < 18.026) && (cwnd < 212))
198  {
199  NS_LOG_WARN ("now " << Now ().As (Time::S) << " cwnd " << cwnd << " (expected >= 212)");
200  g_validationFailed = true;
201  }
202  }
203 }
204 
205 void
206 TraceFirstDctcp (std::ofstream* ofStream, uint32_t bytesMarked, uint32_t bytesAcked, double alpha)
207 {
208  if (g_validate == "")
209  {
210  *ofStream << Simulator::Now ().GetSeconds () << " " << alpha << std::endl;
211  }
212  // Validation checks
213  if (g_validate == "dctcp-80ms")
214  {
215  double now = Simulator::Now ().GetSeconds ();
216  if ((now < 7.5) && (alpha < 0.1))
217  {
218  NS_LOG_WARN ("now " << Now ().As (Time::S) << " alpha " << alpha << " (expected >= 0.1)");
219  g_validationFailed = true;
220  }
221  else if ((now > 11) && (now < 30) && (alpha > 0.01))
222  {
223  NS_LOG_WARN ("now " << Now ().As (Time::S) << " alpha " << alpha << " (expected <= 0.01)");
224  g_validationFailed = true;
225  }
226  else if ((now > 34) && (alpha < 0.015) && (alpha > 0.025))
227  {
228  NS_LOG_WARN ("now " << Now ().As (Time::S) << " alpha " << alpha << " (expected 0.015 <= alpha <= 0.025)");
229  g_validationFailed = true;
230  }
231  }
232  else if (g_validate == "dctcp-10ms")
233  {
234  double now = Simulator::Now ().GetSeconds ();
235  if ((now > 5.6) && (alpha > 0.1))
236  {
237  NS_LOG_WARN ("now " << Now ().As (Time::S) << " alpha " << alpha << " (expected <= 0.1)");
238  g_validationFailed = true;
239  }
240  if ((now > 7) && ((alpha > 0.09) || (alpha < 0.055)))
241  {
242  NS_LOG_WARN ("now " << Now ().As (Time::S) << " alpha " << alpha << " (expected 0.09 <= alpha <= 0.055)");
243  g_validationFailed = true;
244  }
245  }
246 }
247 
248 void
249 TraceFirstRtt (std::ofstream* ofStream, Time oldRtt, Time newRtt)
250 {
251  if (g_validate == "")
252  {
253  *ofStream << Simulator::Now ().GetSeconds () << " " << newRtt.GetSeconds () * 1000 << std::endl;
254  }
255 }
256 
257 void
258 TraceSecondCwnd (std::ofstream* ofStream, uint32_t oldCwnd, uint32_t newCwnd)
259 {
260  // TCP segment size is configured below to be 1448 bytes
261  // so that we can report cwnd in units of segments
262  if (g_validate == "")
263  {
264  *ofStream << Simulator::Now ().GetSeconds () << " " << static_cast<double> (newCwnd) / 1448 << std::endl;
265  }
266 }
267 
268 void
269 TraceSecondRtt (std::ofstream* ofStream, Time oldRtt, Time newRtt)
270 {
271  if (g_validate == "")
272  {
273  *ofStream << Simulator::Now ().GetSeconds () << " " << newRtt.GetSeconds () * 1000 << std::endl;
274  }
275 }
276 
277 void
278 TraceSecondDctcp (std::ofstream* ofStream, uint32_t bytesMarked, uint32_t bytesAcked, double alpha)
279 {
280  if (g_validate == "")
281  {
282  *ofStream << Simulator::Now ().GetSeconds () << " " << alpha << std::endl;
283  }
284 }
285 
286 void
287 TracePingRtt (std::ofstream* ofStream, Time rtt)
288 {
289  if (g_validate == "")
290  {
291  *ofStream << Simulator::Now ().GetSeconds () << " " << rtt.GetSeconds () * 1000 << std::endl;
292  }
293 }
294 
295 void
297 {
298  g_firstBytesReceived += packet->GetSize ();
299 }
300 
301 void
303 {
304  g_secondBytesReceived += packet->GetSize ();
305 }
306 
307 void
308 TraceQueueDrop (std::ofstream* ofStream, Ptr<const QueueDiscItem> item)
309 {
310  if (g_validate == "")
311  {
312  *ofStream << Simulator::Now ().GetSeconds () << " " << std::hex << item->Hash () << std::endl;
313  }
314  g_dropsObserved++;
315 }
316 
317 void
318 TraceQueueMark (std::ofstream* ofStream, Ptr<const QueueDiscItem> item, const char* reason)
319 {
320  if (g_validate == "")
321  {
322  *ofStream << Simulator::Now ().GetSeconds () << " " << std::hex << item->Hash () << std::endl;
323  }
324  g_marksObserved++;
325 }
326 
327 void
328 TraceQueueLength (std::ofstream* ofStream, DataRate queueLinkRate, uint32_t oldVal, uint32_t newVal)
329 {
330  // output in units of ms
331  if (g_validate == "")
332  {
333  *ofStream << Simulator::Now ().GetSeconds () << " " << std::fixed << static_cast<double> (newVal * 8) / (queueLinkRate.GetBitRate () / 1000) << std::endl;
334  }
335 }
336 
337 void
338 TraceMarksFrequency (std::ofstream* ofStream, Time marksSamplingInterval)
339 {
340  if (g_validate == "")
341  {
342  *ofStream << Simulator::Now ().GetSeconds () << " " << g_marksObserved << std::endl;
343  }
344  g_marksObserved = 0;
345  Simulator::Schedule (marksSamplingInterval, &TraceMarksFrequency, ofStream, marksSamplingInterval);
346 }
347 
348 void
349 TraceFirstThroughput (std::ofstream* ofStream, Time throughputInterval)
350 {
351  double throughput = g_firstBytesReceived * 8 / throughputInterval.GetSeconds () / 1e6;
352  if (g_validate == "")
353  {
354  *ofStream << Simulator::Now ().GetSeconds () << " " << throughput << std::endl;
355  }
357  Simulator::Schedule (throughputInterval, &TraceFirstThroughput, ofStream, throughputInterval);
358  if (g_validate == "dctcp-80ms")
359  {
360  double now = Simulator::Now ().GetSeconds ();
361  if ((now < 14) && (throughput > 20))
362  {
363  NS_LOG_WARN ("now " << Now ().As (Time::S) << " throughput " << throughput << " (expected <= 20)");
364  g_validationFailed = true;
365  }
366  if ((now < 30) && (throughput > 48))
367  {
368  NS_LOG_WARN ("now " << Now ().As (Time::S) << " throughput " << throughput << " (expected <= 48)");
369  g_validationFailed = true;
370  }
371  if ((now > 32) && ((throughput < 47.5) || (throughput > 48.5)))
372  {
373  NS_LOG_WARN ("now " << Now ().As (Time::S) << " throughput " << throughput << " (expected 47.5 <= throughput <= 48.5)");
374  g_validationFailed = true;
375  }
376  }
377  else if (g_validate == "dctcp-10ms")
378  {
379  double now = Simulator::Now ().GetSeconds ();
380  if ((now > 5.6) && ((throughput < 48) || (throughput > 49)))
381  {
382  NS_LOG_WARN ("now " << Now ().As (Time::S) << " throughput " << throughput << " (expected 48 <= throughput <= 49)");
383  g_validationFailed = true;
384  }
385  }
386 }
387 
388 void
389 TraceSecondThroughput (std::ofstream* ofStream, Time throughputInterval)
390 {
391  if (g_validate == "")
392  {
393  *ofStream << Simulator::Now ().GetSeconds () << " " << g_secondBytesReceived * 8 / throughputInterval.GetSeconds () / 1e6 << std::endl;
394  }
396  Simulator::Schedule (throughputInterval, &TraceSecondThroughput, ofStream, throughputInterval);
397 }
398 
399 void
400 ScheduleFirstTcpCwndTraceConnection (std::ofstream* ofStream)
401 {
402  Config::ConnectWithoutContextFailSafe ("/NodeList/1/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow", MakeBoundCallback (&TraceFirstCwnd, ofStream));
403 }
404 
405 void
406 ScheduleFirstTcpRttTraceConnection (std::ofstream* ofStream)
407 {
408  Config::ConnectWithoutContextFailSafe ("/NodeList/1/$ns3::TcpL4Protocol/SocketList/0/RTT", MakeBoundCallback (&TraceFirstRtt, ofStream));
409 }
410 
411 void
412 ScheduleFirstDctcpTraceConnection (std::ofstream* ofStream)
413 {
414  Config::ConnectWithoutContextFailSafe ("/NodeList/1/$ns3::TcpL4Protocol/SocketList/0/CongestionOps/$ns3::TcpDctcp/CongestionEstimate", MakeBoundCallback (&TraceFirstDctcp, ofStream));
415 }
416 
417 void
418 ScheduleSecondDctcpTraceConnection (std::ofstream* ofStream)
419 {
420  Config::ConnectWithoutContextFailSafe ("/NodeList/2/$ns3::TcpL4Protocol/SocketList/0/CongestionOps/$ns3::TcpDctcp/CongestionEstimate", MakeBoundCallback (&TraceSecondDctcp, ofStream));
421 }
422 
423 void
425 {
426  Config::ConnectWithoutContextFailSafe ("/NodeList/6/ApplicationList/*/$ns3::PacketSink/Rx", MakeCallback (&TraceFirstRx));
427 }
428 
429 void
430 ScheduleSecondTcpCwndTraceConnection (std::ofstream* ofStream)
431 {
432  Config::ConnectWithoutContext ("/NodeList/2/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow", MakeBoundCallback (&TraceSecondCwnd, ofStream));
433 }
434 
435 void
436 ScheduleSecondTcpRttTraceConnection (std::ofstream* ofStream)
437 {
438  Config::ConnectWithoutContext ("/NodeList/2/$ns3::TcpL4Protocol/SocketList/0/RTT", MakeBoundCallback (&TraceSecondRtt, ofStream));
439 }
440 
441 void
443 {
444  Config::ConnectWithoutContext ("/NodeList/7/ApplicationList/*/$ns3::PacketSink/Rx", MakeCallback (&TraceSecondRx));
445 }
446 
447 int
448 main (int argc, char *argv[])
449 {
451  // variables not configured at command line //
453  uint32_t pingSize = 100; // bytes
454  bool enableSecondTcp = false;
455  bool enableLogging = false;
456  Time pingInterval = MilliSeconds (100);
457  Time marksSamplingInterval = MilliSeconds (100);
458  Time throughputSamplingInterval = MilliSeconds (200);
459  std::string pingTraceFile = "tcp-validation-ping.dat";
460  std::string firstTcpRttTraceFile = "tcp-validation-first-tcp-rtt.dat";
461  std::string firstTcpCwndTraceFile = "tcp-validation-first-tcp-cwnd.dat";
462  std::string firstDctcpTraceFile = "tcp-validation-first-dctcp-alpha.dat";
463  std::string firstTcpThroughputTraceFile = "tcp-validation-first-tcp-throughput.dat";
464  std::string secondTcpRttTraceFile = "tcp-validation-second-tcp-rtt.dat";
465  std::string secondTcpCwndTraceFile = "tcp-validation-second-tcp-cwnd.dat";
466  std::string secondTcpThroughputTraceFile = "tcp-validation-second-tcp-throughput.dat";
467  std::string secondDctcpTraceFile = "tcp-validation-second-dctcp-alpha.dat";
468  std::string queueMarkTraceFile = "tcp-validation-queue-mark.dat";
469  std::string queueDropTraceFile = "tcp-validation-queue-drop.dat";
470  std::string queueMarksFrequencyTraceFile = "tcp-validation-queue-marks-frequency.dat";
471  std::string queueLengthTraceFile = "tcp-validation-queue-length.dat";
472 
474  // variables configured at command line //
476  std::string firstTcpType = "cubic";
477  std::string secondTcpType = "";
478  std::string queueType = "codel";
479  Time stopTime = Seconds (70);
480  Time baseRtt = MilliSeconds (80);
481  DataRate linkRate ("50Mbps");
482  bool queueUseEcn = false;
483  Time ceThreshold = MilliSeconds (1);
484  bool enablePcap = false;
485 
487  // Override ns-3 defaults //
489  Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (1448));
490  // Increase default buffer sizes to improve throughput over long delay paths
491  //Config::SetDefault ("ns3::TcpSocket::SndBufSize",UintegerValue (8192000));
492  //Config::SetDefault ("ns3::TcpSocket::RcvBufSize",UintegerValue (8192000));
493  Config::SetDefault ("ns3::TcpSocket::SndBufSize",UintegerValue (32768000));
494  Config::SetDefault ("ns3::TcpSocket::RcvBufSize",UintegerValue (32768000));
495  Config::SetDefault ("ns3::TcpSocket::InitialCwnd", UintegerValue (10));
496  Config::SetDefault ("ns3::TcpL4Protocol::RecoveryType", TypeIdValue (TcpPrrRecovery::GetTypeId ()));
497 
499  // command-line argument parsing //
502  cmd.AddValue ("firstTcpType", "first TCP type (cubic, dctcp, or reno)", firstTcpType);
503  cmd.AddValue ("secondTcpType", "second TCP type (cubic, dctcp, or reno)", secondTcpType);
504  cmd.AddValue ("queueType", "bottleneck queue type (fq, codel, pie, or red)", queueType);
505  cmd.AddValue ("baseRtt", "base RTT", baseRtt);
506  cmd.AddValue ("ceThreshold", "CoDel CE threshold (for DCTCP)", ceThreshold);
507  cmd.AddValue ("linkRate", "data rate of bottleneck link", linkRate);
508  cmd.AddValue ("stopTime", "simulation stop time", stopTime);
509  cmd.AddValue ("queueUseEcn", "use ECN on queue", queueUseEcn);
510  cmd.AddValue ("enablePcap", "enable Pcap", enablePcap);
511  cmd.AddValue ("validate", "validation case to run", g_validate);
512  cmd.Parse (argc, argv);
513 
514  // If validation is selected, perform some configuration checks
515  if (g_validate != "")
516  {
517  NS_ABORT_MSG_UNLESS (g_validate == "dctcp-10ms"
518  || g_validate == "dctcp-80ms"
519  || g_validate == "cubic-50ms-no-ecn"
520  || g_validate == "cubic-50ms-ecn", "Unknown test");
521  if (g_validate == "dctcp-10ms" || g_validate == "dctcp-80ms")
522  {
523  NS_ABORT_MSG_UNLESS (firstTcpType == "dctcp", "Incorrect TCP");
524  NS_ABORT_MSG_UNLESS (secondTcpType == "", "Incorrect TCP");
525  NS_ABORT_MSG_UNLESS (linkRate == DataRate ("50Mbps"), "Incorrect data rate");
526  NS_ABORT_MSG_UNLESS (queueUseEcn == true, "Incorrect ECN configuration");
527  NS_ABORT_MSG_UNLESS (stopTime >= Seconds (15), "Incorrect stopTime");
528  if (g_validate == "dctcp-10ms")
529  {
530  NS_ABORT_MSG_UNLESS (baseRtt == MilliSeconds (10), "Incorrect RTT");
531  }
532  else if (g_validate == "dctcp-80ms")
533  {
534  NS_ABORT_MSG_UNLESS (baseRtt == MilliSeconds (80), "Incorrect RTT");
535  }
536  }
537  else if (g_validate == "cubic-50ms-no-ecn" || g_validate == "cubic-50ms-ecn")
538  {
539  NS_ABORT_MSG_UNLESS (firstTcpType == "cubic", "Incorrect TCP");
540  NS_ABORT_MSG_UNLESS (secondTcpType == "", "Incorrect TCP");
541  NS_ABORT_MSG_UNLESS (baseRtt == MilliSeconds (50), "Incorrect RTT");
542  NS_ABORT_MSG_UNLESS (linkRate == DataRate ("50Mbps"), "Incorrect data rate");
543  NS_ABORT_MSG_UNLESS (stopTime >= Seconds (20), "Incorrect stopTime");
544  if (g_validate == "cubic-50ms-no-ecn")
545  {
546  NS_ABORT_MSG_UNLESS (queueUseEcn == false, "Incorrect ECN configuration");
547  }
548  else if (g_validate == "cubic-50ms-ecn")
549  {
550  NS_ABORT_MSG_UNLESS (queueUseEcn == true, "Incorrect ECN configuration");
551  }
552  }
553  }
554 
555  if (enableLogging)
556  {
559  }
560 
561  Time oneWayDelay = baseRtt / 2;
562 
563  TypeId firstTcpTypeId;
564  if (firstTcpType == "reno")
565  {
566  firstTcpTypeId = TcpLinuxReno::GetTypeId ();
567  }
568  else if (firstTcpType == "cubic")
569  {
570  firstTcpTypeId = TcpCubic::GetTypeId ();
571  }
572  else if (firstTcpType == "dctcp")
573  {
574  firstTcpTypeId = TcpDctcp::GetTypeId ();
575  Config::SetDefault ("ns3::CoDelQueueDisc::CeThreshold", TimeValue (ceThreshold));
576  Config::SetDefault ("ns3::FqCoDelQueueDisc::CeThreshold", TimeValue (ceThreshold));
577  if (queueUseEcn == false)
578  {
579  std::cout << "Warning: using DCTCP with queue ECN disabled" << std::endl;
580  }
581  }
582  else
583  {
584  NS_FATAL_ERROR ("Fatal error: tcp unsupported");
585  }
586  TypeId secondTcpTypeId;
587  if (secondTcpType == "reno")
588  {
589  enableSecondTcp = true;
590  secondTcpTypeId = TcpLinuxReno::GetTypeId ();
591  }
592  else if (secondTcpType == "cubic")
593  {
594  enableSecondTcp = true;
595  secondTcpTypeId = TcpCubic::GetTypeId ();
596  }
597  else if (secondTcpType == "dctcp")
598  {
599  enableSecondTcp = true;
600  secondTcpTypeId = TcpDctcp::GetTypeId ();
601  }
602  else if (secondTcpType == "")
603  {
604  enableSecondTcp = false;
605  NS_LOG_DEBUG ("No second TCP selected");
606  }
607  else
608  {
609  NS_FATAL_ERROR ("Fatal error: tcp unsupported");
610  }
611  TypeId queueTypeId;
612  if (queueType == "fq")
613  {
614  queueTypeId = FqCoDelQueueDisc::GetTypeId ();
615  }
616  else if (queueType == "codel")
617  {
618  queueTypeId = CoDelQueueDisc::GetTypeId ();
619  }
620  else if (queueType == "pie")
621  {
622  queueTypeId = PieQueueDisc::GetTypeId ();
623  }
624  else if (queueType == "red")
625  {
626  queueTypeId = RedQueueDisc::GetTypeId ();
627  }
628  else
629  {
630  NS_FATAL_ERROR ("Fatal error: queueType unsupported");
631  }
632 
633  if (queueUseEcn)
634  {
635  Config::SetDefault ("ns3::CoDelQueueDisc::UseEcn", BooleanValue (true));
636  Config::SetDefault ("ns3::FqCoDelQueueDisc::UseEcn", BooleanValue (true));
637  Config::SetDefault ("ns3::PieQueueDisc::UseEcn", BooleanValue (true));
638  Config::SetDefault ("ns3::RedQueueDisc::UseEcn", BooleanValue (true));
639  }
640  // Enable TCP to use ECN regardless
641  Config::SetDefault ("ns3::TcpSocketBase::UseEcn", StringValue ("On"));
642 
643  // Report on configuration
644  if (enableSecondTcp)
645  {
646  NS_LOG_DEBUG ("first TCP: " << firstTcpTypeId.GetName () << "; second TCP: " << secondTcpTypeId.GetName () << "; queue: " << queueTypeId.GetName () << "; ceThreshold: " << ceThreshold.GetSeconds () * 1000 << "ms");
647  }
648  else
649  {
650  NS_LOG_DEBUG ("first TCP: " << firstTcpTypeId.GetName () << "; queue: " << queueTypeId.GetName () << "; ceThreshold: " << ceThreshold.GetSeconds () * 1000 << "ms");
651  }
652 
653  // Write traces only if we are not in validation mode (g_validate == "")
654  std::ofstream pingOfStream;
655  std::ofstream firstTcpRttOfStream;
656  std::ofstream firstTcpCwndOfStream;
657  std::ofstream firstTcpThroughputOfStream;
658  std::ofstream firstTcpDctcpOfStream;
659  std::ofstream secondTcpRttOfStream;
660  std::ofstream secondTcpCwndOfStream;
661  std::ofstream secondTcpThroughputOfStream;
662  std::ofstream secondTcpDctcpOfStream;
663  std::ofstream queueDropOfStream;
664  std::ofstream queueMarkOfStream;
665  std::ofstream queueMarksFrequencyOfStream;
666  std::ofstream queueLengthOfStream;
667  if (g_validate == "")
668  {
669  pingOfStream.open (pingTraceFile.c_str (), std::ofstream::out);
670  firstTcpRttOfStream.open (firstTcpRttTraceFile.c_str (), std::ofstream::out);
671  firstTcpCwndOfStream.open (firstTcpCwndTraceFile.c_str (), std::ofstream::out);
672  firstTcpThroughputOfStream.open (firstTcpThroughputTraceFile.c_str (), std::ofstream::out);
673  if (firstTcpType == "dctcp")
674  {
675  firstTcpDctcpOfStream.open (firstDctcpTraceFile.c_str (), std::ofstream::out);
676  }
677  if (enableSecondTcp)
678  {
679  secondTcpRttOfStream.open (secondTcpRttTraceFile.c_str (), std::ofstream::out);
680  secondTcpCwndOfStream.open (secondTcpCwndTraceFile.c_str (), std::ofstream::out);
681  secondTcpThroughputOfStream.open (secondTcpThroughputTraceFile.c_str (), std::ofstream::out);
682  if (secondTcpType == "dctcp")
683  {
684  secondTcpDctcpOfStream.open (secondDctcpTraceFile.c_str (), std::ofstream::out);
685  }
686  }
687  queueDropOfStream.open (queueDropTraceFile.c_str (), std::ofstream::out);
688  queueMarkOfStream.open (queueMarkTraceFile.c_str (), std::ofstream::out);
689  queueMarksFrequencyOfStream.open (queueMarksFrequencyTraceFile.c_str (), std::ofstream::out);
690  queueLengthOfStream.open (queueLengthTraceFile.c_str (), std::ofstream::out);
691  }
692 
694  // scenario setup //
696  Ptr<Node> pingServer = CreateObject<Node> ();
697  Ptr<Node> firstServer = CreateObject<Node> ();
698  Ptr<Node> secondServer = CreateObject<Node> ();
699  Ptr<Node> wanRouter = CreateObject<Node> ();
700  Ptr<Node> lanRouter = CreateObject<Node> ();
701  Ptr<Node> pingClient = CreateObject<Node> ();
702  Ptr<Node> firstClient = CreateObject<Node> ();
703  Ptr<Node> secondClient = CreateObject<Node> ();
704 
705  // Device containers
706  NetDeviceContainer pingServerDevices;
707  NetDeviceContainer firstServerDevices;
708  NetDeviceContainer secondServerDevices;
709  NetDeviceContainer wanLanDevices;
710  NetDeviceContainer pingClientDevices;
711  NetDeviceContainer firstClientDevices;
712  NetDeviceContainer secondClientDevices;
713 
714  PointToPointHelper p2p;
715  p2p.SetQueue ("ns3::DropTailQueue", "MaxSize", QueueSizeValue (QueueSize ("3p")));
716  p2p.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("1000Mbps")));
717  // Add delay only on the WAN links
718  p2p.SetChannelAttribute ("Delay", TimeValue (MicroSeconds (1)));
719  pingServerDevices = p2p.Install (wanRouter, pingServer);
720  firstServerDevices = p2p.Install (wanRouter, firstServer);
721  secondServerDevices = p2p.Install (wanRouter, secondServer);
722  p2p.SetChannelAttribute ("Delay", TimeValue (oneWayDelay));
723  wanLanDevices = p2p.Install (wanRouter, lanRouter);
724  p2p.SetQueue ("ns3::DropTailQueue", "MaxSize", QueueSizeValue (QueueSize ("3p")));
725  p2p.SetChannelAttribute ("Delay", TimeValue (MicroSeconds (1)));
726  pingClientDevices = p2p.Install (lanRouter, pingClient);
727  firstClientDevices = p2p.Install (lanRouter, firstClient);
728  secondClientDevices = p2p.Install (lanRouter, secondClient);
729 
730  // Limit the bandwidth on the wanRouter->lanRouter interface
732  p->SetAttribute ("DataRate", DataRateValue (linkRate));
733 
734  InternetStackHelper stackHelper;
735  stackHelper.Install (pingServer);
736  Ptr<TcpL4Protocol> proto;
737  stackHelper.Install (firstServer);
738  proto = firstServer->GetObject<TcpL4Protocol> ();
739  proto->SetAttribute ("SocketType", TypeIdValue (firstTcpTypeId));
740  stackHelper.Install (secondServer);
741  stackHelper.Install (wanRouter);
742  stackHelper.Install (lanRouter);
743  stackHelper.Install (pingClient);
744 
745  stackHelper.Install (firstClient);
746  // Set the per-node TCP type here
747  proto = firstClient->GetObject<TcpL4Protocol> ();
748  proto->SetAttribute ("SocketType", TypeIdValue (firstTcpTypeId));
749  stackHelper.Install (secondClient);
750 
751  if (enableSecondTcp)
752  {
753  proto = secondClient->GetObject<TcpL4Protocol> ();
754  proto->SetAttribute ("SocketType", TypeIdValue (secondTcpTypeId));
755  proto = secondServer->GetObject<TcpL4Protocol> ();
756  proto->SetAttribute ("SocketType", TypeIdValue (secondTcpTypeId));
757  }
758 
759  // InternetStackHelper will install a base TrafficControLayer on the node,
760  // but the Ipv4AddressHelper below will install the default FqCoDelQueueDisc
761  // on all single device nodes. The below code overrides the configuration
762  // that is normally done by the Ipv4AddressHelper::Install() method by
763  // instead explicitly configuring the queue discs we want on each device.
764  TrafficControlHelper tchFq;
765  tchFq.SetRootQueueDisc ("ns3::FqCoDelQueueDisc");
766  tchFq.SetQueueLimits ("ns3::DynamicQueueLimits", "HoldTime", StringValue ("1ms"));
767  tchFq.Install (pingServerDevices);
768  tchFq.Install (firstServerDevices);
769  tchFq.Install (secondServerDevices);
770  tchFq.Install (wanLanDevices.Get (1));
771  tchFq.Install (pingClientDevices);
772  tchFq.Install (firstClientDevices);
773  tchFq.Install (secondClientDevices);
774  // Install queue for bottleneck link
775  TrafficControlHelper tchBottleneck;
776  tchBottleneck.SetRootQueueDisc (queueTypeId.GetName ());
777  tchBottleneck.SetQueueLimits ("ns3::DynamicQueueLimits", "HoldTime", StringValue ("1ms"));
778  tchBottleneck.Install (wanLanDevices.Get (0));
779 
780  Ipv4AddressHelper ipv4;
781  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
782  Ipv4InterfaceContainer pingServerIfaces = ipv4.Assign (pingServerDevices);
783  ipv4.SetBase ("10.1.2.0", "255.255.255.0");
784  Ipv4InterfaceContainer firstServerIfaces = ipv4.Assign (firstServerDevices);
785  ipv4.SetBase ("10.1.3.0", "255.255.255.0");
786  Ipv4InterfaceContainer secondServerIfaces = ipv4.Assign (secondServerDevices);
787  ipv4.SetBase ("172.16.1.0", "255.255.255.0");
788  Ipv4InterfaceContainer wanLanIfaces = ipv4.Assign (wanLanDevices);
789  ipv4.SetBase ("192.168.1.0", "255.255.255.0");
790  Ipv4InterfaceContainer pingClientIfaces = ipv4.Assign (pingClientDevices);
791  ipv4.SetBase ("192.168.2.0", "255.255.255.0");
792  Ipv4InterfaceContainer firstClientIfaces = ipv4.Assign (firstClientDevices);
793  ipv4.SetBase ("192.168.3.0", "255.255.255.0");
794  Ipv4InterfaceContainer secondClientIfaces = ipv4.Assign (secondClientDevices);
795 
797 
799  // application setup //
801  V4PingHelper pingHelper ("192.168.1.2");
802  pingHelper.SetAttribute ("Interval", TimeValue (pingInterval));
803  pingHelper.SetAttribute ("Size", UintegerValue (pingSize));
804  ApplicationContainer pingContainer = pingHelper.Install (pingServer);
805  Ptr<V4Ping> v4Ping = pingContainer.Get (0)->GetObject<V4Ping> ();
806  v4Ping->TraceConnectWithoutContext ("Rtt", MakeBoundCallback (&TracePingRtt, &pingOfStream));
807  pingContainer.Start (Seconds (1));
808  pingContainer.Stop (stopTime - Seconds (1));
809 
810  ApplicationContainer firstApp;
811  uint16_t firstPort = 5000;
812  BulkSendHelper tcp ("ns3::TcpSocketFactory", Address ());
813  // set to large value: e.g. 1000 Mb/s for 60 seconds = 7500000000 bytes
814  tcp.SetAttribute ("MaxBytes", UintegerValue (7500000000));
815  // Configure first TCP client/server pair
816  InetSocketAddress firstDestAddress (firstClientIfaces.GetAddress (1), firstPort);
817  tcp.SetAttribute ("Remote", AddressValue (firstDestAddress));
818  firstApp = tcp.Install (firstServer);
819  firstApp.Start (Seconds (5));
820  firstApp.Stop (stopTime - Seconds (1));
821 
822  Address firstSinkAddress (InetSocketAddress (Ipv4Address::GetAny (), firstPort));
823  ApplicationContainer firstSinkApp;
824  PacketSinkHelper firstSinkHelper ("ns3::TcpSocketFactory", firstSinkAddress);
825  firstSinkApp = firstSinkHelper.Install (firstClient);
826  firstSinkApp.Start (Seconds (5));
827  firstSinkApp.Stop (stopTime - MilliSeconds (500));
828 
829  // Configure second TCP client/server pair
830  if (enableSecondTcp)
831  {
832  BulkSendHelper tcp ("ns3::TcpSocketFactory", Address ());
833  uint16_t secondPort = 5000;
834  ApplicationContainer secondApp;
835  InetSocketAddress secondDestAddress (secondClientIfaces.GetAddress (1), secondPort);
836  tcp.SetAttribute ("Remote", AddressValue (secondDestAddress));
837  secondApp = tcp.Install (secondServer);
838  secondApp.Start (Seconds (15));
839  secondApp.Stop (stopTime - Seconds (1));
840 
841  Address secondSinkAddress (InetSocketAddress (Ipv4Address::GetAny (), secondPort));
842  PacketSinkHelper secondSinkHelper ("ns3::TcpSocketFactory", secondSinkAddress);
843  ApplicationContainer secondSinkApp;
844  secondSinkApp = secondSinkHelper.Install (secondClient);
845  secondSinkApp.Start (Seconds (15));
846  secondSinkApp.Stop (stopTime - MilliSeconds (500));
847  }
848 
849  // Setup traces that can be hooked now
851  Ptr<QueueDisc> qd;
852  // Trace drops and marks for bottleneck
853  tc = wanLanDevices.Get (0)->GetNode ()->GetObject<TrafficControlLayer> ();
854  qd = tc->GetRootQueueDiscOnDevice (wanLanDevices.Get (0));
855  qd->TraceConnectWithoutContext ("Drop", MakeBoundCallback (&TraceQueueDrop, &queueDropOfStream));
856  qd->TraceConnectWithoutContext ("Mark", MakeBoundCallback (&TraceQueueMark, &queueMarkOfStream));
857  qd->TraceConnectWithoutContext ("BytesInQueue", MakeBoundCallback (&TraceQueueLength, &queueLengthOfStream, linkRate));
858 
859  // Setup scheduled traces; TCP traces must be hooked after socket creation
860  Simulator::Schedule (Seconds (5) + MilliSeconds (100), &ScheduleFirstTcpRttTraceConnection, &firstTcpRttOfStream);
861  Simulator::Schedule (Seconds (5) + MilliSeconds (100), &ScheduleFirstTcpCwndTraceConnection, &firstTcpCwndOfStream);
863  if (firstTcpType == "dctcp")
864  {
865  Simulator::Schedule (Seconds (5) + MilliSeconds (100), &ScheduleFirstDctcpTraceConnection, &firstTcpDctcpOfStream);
866  }
867  Simulator::Schedule (throughputSamplingInterval, &TraceFirstThroughput, &firstTcpThroughputOfStream, throughputSamplingInterval);
868  if (enableSecondTcp)
869  {
870  // Setup scheduled traces; TCP traces must be hooked after socket creation
871  Simulator::Schedule (Seconds (15) + MilliSeconds (100), &ScheduleSecondTcpRttTraceConnection, &secondTcpRttOfStream);
872  Simulator::Schedule (Seconds (15) + MilliSeconds (100), &ScheduleSecondTcpCwndTraceConnection, &secondTcpCwndOfStream);
874  Simulator::Schedule (throughputSamplingInterval, &TraceSecondThroughput, &secondTcpThroughputOfStream, throughputSamplingInterval);
875  if (secondTcpType == "dctcp")
876  {
877  Simulator::Schedule (Seconds (15) + MilliSeconds (100), &ScheduleSecondDctcpTraceConnection, &secondTcpDctcpOfStream);
878  }
879  }
880  Simulator::Schedule (marksSamplingInterval, &TraceMarksFrequency, &queueMarksFrequencyOfStream, marksSamplingInterval);
881 
882  if (enablePcap)
883  {
884  p2p.EnablePcapAll ("tcp-validation", false);
885  }
886 
888  Simulator::Run ();
890 
891  if (g_validate == "")
892  {
893  pingOfStream.close ();
894  firstTcpCwndOfStream.close ();
895  firstTcpRttOfStream.close ();
896  if (firstTcpType == "dctcp")
897  {
898  firstTcpDctcpOfStream.close ();
899  }
900  firstTcpThroughputOfStream.close ();
901  if (enableSecondTcp)
902  {
903  secondTcpCwndOfStream.close ();
904  secondTcpRttOfStream.close ();
905  secondTcpThroughputOfStream.close ();
906  if (secondTcpType == "dctcp")
907  {
908  secondTcpDctcpOfStream.close ();
909  }
910  }
911  queueDropOfStream.close ();
912  queueMarkOfStream.close ();
913  queueMarksFrequencyOfStream.close ();
914  queueLengthOfStream.close ();
915  }
916 
917  if (g_validationFailed)
918  {
919  NS_FATAL_ERROR ("Validation failed");
920  }
921 }
922 
ns3::NetDeviceContainer
holds a vector of ns3::NetDevice pointers
Definition: net-device-container.h:42
ns3::TypeId
a unique identifier for an interface.
Definition: type-id.h:59
NS_LOG_COMPONENT_DEFINE
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
ns3::InetSocketAddress
an Inet address class
Definition: inet-socket-address.h:41
ns3::DataRateValue
AttributeValue implementation for DataRate.
Definition: data-rate.h:298
ns3::ApplicationContainer::Get
Ptr< Application > Get(uint32_t i) const
Get the Ptr<Application> stored in this container at a given index.
Definition: application-container.cc:62
TraceQueueMark
void TraceQueueMark(std::ofstream *ofStream, Ptr< const QueueDiscItem > item, const char *reason)
Definition: tcp-validation.cc:318
ScheduleSecondTcpCwndTraceConnection
void ScheduleSecondTcpCwndTraceConnection(std::ofstream *ofStream)
Definition: tcp-validation.cc:430
ns3::CommandLine
Parse command-line arguments.
Definition: command-line.h:228
stopTime
Time stopTime
Definition: tcp-linux-reno.cc:52
ns3::BooleanValue
AttributeValue implementation for Boolean.
Definition: boolean.h:37
ns3::TcpPrrRecovery::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: tcp-prr-recovery.cc:35
ns3::TrafficControlHelper::SetRootQueueDisc
uint16_t SetRootQueueDisc(const std::string &type, Args &&... args)
Helper function used to set a root queue disc of the given type and with the given attributes.
Definition: traffic-control-helper.h:360
ns3::Packet::GetSize
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
g_marksObserved
uint32_t g_marksObserved
Definition: tcp-validation.cc:163
ns3::Simulator::Now
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
ns3
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::ApplicationContainer::Stop
void Stop(Time stop)
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
Definition: application-container.cc:107
ns3::TcpDctcp::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: tcp-dctcp.cc:33
ns3::PointToPointHelper::SetQueue
void SetQueue(std::string type, std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue())
Each point to point net device must have a queue to pass packets through.
Definition: point-to-point-helper.cc:53
ns3::Ipv4AddressHelper
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
Definition: ipv4-address-helper.h:48
TraceSecondRtt
void TraceSecondRtt(std::ofstream *ofStream, Time oldRtt, Time newRtt)
Definition: tcp-validation.cc:269
ns3::TcpCubic::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: tcp-cubic.cc:33
ns3::PointToPointHelper::SetDeviceAttribute
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
Definition: point-to-point-helper.cc:69
ns3::PointToPointHelper::SetChannelAttribute
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
Definition: point-to-point-helper.cc:75
ns3::MicroSeconds
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
ns3::LOG_PREFIX_NODE
@ LOG_PREFIX_NODE
Prefix all trace prints with simulation node.
Definition: log.h:120
g_secondBytesReceived
uint32_t g_secondBytesReceived
Definition: tcp-validation.cc:162
ns3::PcapHelperForDevice::EnablePcapAll
void EnablePcapAll(std::string prefix, bool promiscuous=false)
Enable pcap output on each device (which is of the appropriate type) in the set of all nodes created ...
Definition: trace-helper.cc:439
ns3::Object::GetObject
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
ns3::AddressValue
AttributeValue implementation for Address.
Definition: address.h:278
TraceMarksFrequency
void TraceMarksFrequency(std::ofstream *ofStream, Time marksSamplingInterval)
Definition: tcp-validation.cc:338
ns3::LOG_LEVEL_ALL
@ LOG_LEVEL_ALL
Print everything.
Definition: log.h:116
NS_LOG_WARN
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
ScheduleFirstTcpCwndTraceConnection
void ScheduleFirstTcpCwndTraceConnection(std::ofstream *ofStream)
Definition: tcp-validation.cc:400
ns3::LogComponentEnable
void LogComponentEnable(char const *name, enum LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:361
ns3::PointToPointHelper::Install
NetDeviceContainer Install(NodeContainer c)
Definition: point-to-point-helper.cc:222
TracePingRtt
void TracePingRtt(std::ofstream *ofStream, Time rtt)
Definition: tcp-validation.cc:287
ns3::BulkSendHelper
A helper to make it easier to instantiate an ns3::BulkSendApplication on a set of nodes.
Definition: bulk-send-helper.h:43
ns3::ObjectBase::SetAttribute
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
ns3::V4Ping
an application which sends one ICMP ECHO request, waits for a REPLYs and reports the calculated RTT.
Definition: v4ping.h:42
ScheduleFirstPacketSinkConnection
void ScheduleFirstPacketSinkConnection(void)
Definition: tcp-validation.cc:424
ns3::Simulator::Schedule
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
ns3::QueueSizeValue
Definition: queue-size.h:221
ns3::Ipv4AddressHelper::SetBase
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Definition: ipv4-address-helper.cc:64
TraceFirstRtt
void TraceFirstRtt(std::ofstream *ofStream, Time oldRtt, Time newRtt)
Definition: tcp-validation.cc:249
ns3::Ptr< const Packet >
NS_FATAL_ERROR
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
ns3::DataRate
Class for representing data rates.
Definition: data-rate.h:89
ns3::Config::ConnectWithoutContext
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:901
ScheduleSecondTcpRttTraceConnection
void ScheduleSecondTcpRttTraceConnection(std::ofstream *ofStream)
Definition: tcp-validation.cc:436
ns3::TcpLinuxReno::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: tcp-linux-reno.cc:33
ns3::TypeIdValue
AttributeValue implementation for TypeId.
Definition: type-id.h:595
ns3::Ipv4GlobalRoutingHelper::PopulateRoutingTables
static void PopulateRoutingTables(void)
Build a routing database and initialize the routing tables of the nodes in the simulation.
Definition: ipv4-global-routing-helper.cc:61
ns3::TrafficControlHelper::SetQueueLimits
void SetQueueLimits(std::string type, Args &&... args)
Helper function used to add a queue limits object to the transmission queues of the devices.
Definition: traffic-control-helper.h:407
ns3::Simulator::Stop
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:180
ns3::Now
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
ns3::TrafficControlHelper::Install
QueueDiscContainer Install(NetDeviceContainer c)
Definition: traffic-control-helper.cc:248
ns3::Address
a polymophic address class
Definition: address.h:91
sample-rng-plot.alpha
alpha
Definition: sample-rng-plot.py:37
ns3::V4PingHelper
Create a IPv4 ping application and associate it to a node.
Definition: v4ping-helper.h:38
ns3::InternetStackHelper::Install
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
Definition: internet-stack-helper.cc:366
TraceFirstThroughput
void TraceFirstThroughput(std::ofstream *ofStream, Time throughputInterval)
Definition: tcp-validation.cc:349
ns3::FqCoDelQueueDisc::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: fq-codel-queue-disc.cc:109
ns3::NetDevice::GetNode
virtual Ptr< Node > GetNode(void) const =0
ns3::MilliSeconds
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1297
ns3::Ipv4InterfaceContainer
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Definition: ipv4-interface-container.h:55
g_validate
std::string g_validate
Definition: tcp-validation.cc:165
first.address
address
Definition: first.py:44
ns3::Config::ConnectWithoutContextFailSafe
bool ConnectWithoutContextFailSafe(std::string path, const CallbackBase &cb)
This function will attempt to find all trace sources which match the input path and will then connect...
Definition: config.cc:909
ns3::Time
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
TraceSecondDctcp
void TraceSecondDctcp(std::ofstream *ofStream, uint32_t bytesMarked, uint32_t bytesAcked, double alpha)
Definition: tcp-validation.cc:278
second.cmd
cmd
Definition: second.py:35
TraceQueueDrop
void TraceQueueDrop(std::ofstream *ofStream, Ptr< const QueueDiscItem > item)
Definition: tcp-validation.cc:308
TraceFirstCwnd
void TraceFirstCwnd(std::ofstream *ofStream, uint32_t oldCwnd, uint32_t newCwnd)
Definition: tcp-validation.cc:169
TraceSecondRx
void TraceSecondRx(Ptr< const Packet > packet, const Address &address)
Definition: tcp-validation.cc:302
ns3::DataRate::GetBitRate
uint64_t GetBitRate() const
Get the underlying bitrate.
Definition: data-rate.cc:287
TraceFirstDctcp
void TraceFirstDctcp(std::ofstream *ofStream, uint32_t bytesMarked, uint32_t bytesAcked, double alpha)
Definition: tcp-validation.cc:206
ns3::PieQueueDisc::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: pie-queue-disc.cc:43
ns3::MakeCallback
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642
ns3::Simulator::Run
static void Run(void)
Run the simulation.
Definition: simulator.cc:172
ns3::StringValue
Hold variables of type string.
Definition: string.h:41
ScheduleFirstTcpRttTraceConnection
void ScheduleFirstTcpRttTraceConnection(std::ofstream *ofStream)
Definition: tcp-validation.cc:406
ns3::PacketSinkHelper
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
Definition: packet-sink-helper.h:36
NS_ABORT_MSG_UNLESS
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition: abort.h:144
TraceQueueLength
void TraceQueueLength(std::ofstream *ofStream, DataRate queueLinkRate, uint32_t oldVal, uint32_t newVal)
Definition: tcp-validation.cc:328
ns3::LOG_PREFIX_TIME
@ LOG_PREFIX_TIME
Prefix all trace prints with simulation time.
Definition: log.h:119
ns3::TypeId::GetName
std::string GetName(void) const
Get the name.
Definition: type-id.cc:977
ns3::Ipv4Address::GetAny
static Ipv4Address GetAny(void)
Definition: ipv4-address.cc:395
NS_LOG_DEBUG
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
g_firstBytesReceived
uint32_t g_firstBytesReceived
Definition: tcp-validation.cc:161
ns3::TrafficControlLayer
Introspection did not find any typical Config paths.
Definition: traffic-control-layer.h:90
TraceFirstRx
void TraceFirstRx(Ptr< const Packet > packet, const Address &address)
Definition: tcp-validation.cc:296
ns3::ApplicationContainer::Start
void Start(Time start)
Arrange for all of the Applications in this container to Start() at the Time given as a parameter.
Definition: application-container.cc:87
ns3::Seconds
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
ns3::MakeBoundCallback
Callback< R > MakeBoundCallback(R(*fnPtr)(TX), ARG a1)
Make Callbacks with one bound argument.
Definition: callback.h:1703
ns3::LOG_PREFIX_FUNC
@ LOG_PREFIX_FUNC
Prefix all trace prints with function.
Definition: log.h:118
ns3::TrafficControlHelper
Build a set of QueueDisc objects.
Definition: traffic-control-helper.h:120
ns3::Ipv4AddressHelper::Assign
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
Definition: ipv4-address-helper.cc:135
ns3::Time::S
@ S
second
Definition: nstime.h:115
ns3::Simulator::Destroy
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:136
ns3::LogLevel
LogLevel
Logging severity classes and levels.
Definition: log.h:94
ns3::ApplicationContainer
holds a vector of ns3::Application pointers.
Definition: application-container.h:43
ns3::TrafficControlLayer::GetRootQueueDiscOnDevice
virtual Ptr< QueueDisc > GetRootQueueDiscOnDevice(Ptr< NetDevice > device) const
This method can be used to get the root queue disc installed on a device.
Definition: traffic-control-layer.cc:224
ns3::TimeValue
AttributeValue implementation for Time.
Definition: nstime.h:1353
ns3::PointToPointNetDevice
A Device for a Point to Point Network Link.
Definition: point-to-point-net-device.h:63
ns3::PointToPointHelper
Build a set of PointToPointNetDevice objects.
Definition: point-to-point-helper.h:45
ns3::RedQueueDisc::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: red-queue-disc.cc:74
ns3::Ipv4InterfaceContainer::GetAddress
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
Definition: ipv4-interface-container.cc:59
ns3::TcpL4Protocol
TCP socket creation and multiplexing/demultiplexing.
Definition: tcp-l4-protocol.h:80
ns3::UintegerValue
Hold an unsigned integer type.
Definition: uinteger.h:44
TraceSecondThroughput
void TraceSecondThroughput(std::ofstream *ofStream, Time throughputInterval)
Definition: tcp-validation.cc:389
ns3::Config::SetDefault
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
ns3::ObjectBase::TraceConnectWithoutContext
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:293
ns3::QueueDiscItem::Hash
virtual uint32_t Hash(uint32_t perturbation=0) const
Computes the hash of various fields of the packet header.
Definition: queue-item.cc:143
ns3::QueueSize
Class for representing queue sizes.
Definition: queue-size.h:95
ns3::InternetStackHelper
aggregate IP/TCP/UDP functionality to existing Nodes.
Definition: internet-stack-helper.h:88
ScheduleSecondDctcpTraceConnection
void ScheduleSecondDctcpTraceConnection(std::ofstream *ofStream)
Definition: tcp-validation.cc:418
ns3::CoDelQueueDisc::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: codel-queue-disc.cc:70
ns3::NetDeviceContainer::Get
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
Definition: net-device-container.cc:62
ScheduleFirstDctcpTraceConnection
void ScheduleFirstDctcpTraceConnection(std::ofstream *ofStream)
Definition: tcp-validation.cc:412
g_dropsObserved
uint32_t g_dropsObserved
Definition: tcp-validation.cc:164
ScheduleSecondPacketSinkConnection
void ScheduleSecondPacketSinkConnection(void)
Definition: tcp-validation.cc:442
ns3::Time::GetSeconds
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:380
enablePcap
bool enablePcap
Definition: tcp-nsc-comparison.cc:48
g_validationFailed
bool g_validationFailed
Definition: tcp-validation.cc:166
TraceSecondCwnd
void TraceSecondCwnd(std::ofstream *ofStream, uint32_t oldCwnd, uint32_t newCwnd)
Definition: tcp-validation.cc:258