A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
fqcodel-l4s-example.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 NITK Surathkal
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors: Bhaskar Kataria <bhaskar.k7920@gmail.com>
7 * Tom Henderson <tomhend@u.washington.edu>
8 * Mohit P. Tahiliani <tahiliani@nitk.edu.in>
9 * Vivek Jain <jain.vivek.anand@gmail.com>
10 * Ankit Deepak <adadeepak8@gmail.com>
11 * This script is written using Tom Henderson's L4S evaluation available at
12 * https://gitlab.com/tomhend/modules/l4s-evaluation
13 */
14
15// The 9 configurations below test BIC and DCTCP under various scenarios.
16// Scenarios are numbered 1-9. By default, scenario number 0 (i.e., no
17// scenario) is configured, which means that the user is free to set
18// any of the parameters freely; if scenarios 1 through 9 are selected,
19// the scenario parameters are fixed.
20//
21// The configuration of the scenarios starts from basic TCP BIC without ECN
22// with the base RTT of 80ms and then in the next scenario, ECN is enabled,
23// and gradually, the complexity of the scenario increases and the last scenario
24// consists of 2 flows one with BIC and other with DCTCP and finally tests
25// The performance of the L4S mode of FqCoDel queue disc.
26
27/** Network topology - For Configuration 1, 2
28 *
29 * 1Gbps, 40ms 100Mbps, 1us 1Gbps, 1us
30 * n0 ---------- n2 ---------------- n3 --------------n4
31 *
32 * Configuration 1: single flow TCP BIC without ECN, base RTT of 80 ms
33 *
34 * Expected Result:
35 * Throughput: Oscillating around 100ms.
36 * Ping RTT: Oscillating between 80ms and 80.5ms
37 * Drop frequency: Should be around 1 drop per 100ms with around 9 spikes in 10 seconds
38 * Length: below 5ms but with frequent spikes
39 * Mark Frequency: There should not be any marks
40 * Congestion Window: Oscillating between around 600 segments and 800 segments
41 * TCP RTT: Oscillating below 5ms frequent spikes up to 90ms
42 * Queue Delay-N0: Below 5ms with frequent spikes
43 *
44 * Configuration 2: single flow TCP BIC with ECN, base RTT of 80 ms
45 *
46 * Expected Result:
47 * Throughput: Reaching 100Mbps and oscillating more than the previous configuration.
48 * Ping RTT: Oscillating between 80ms and 80.5ms
49 * Drop frequency: There should not be any drops
50 * Length: Below 5ms with frequent spikes, average around 3ms
51 * Mark Frequency: Should be around 1 mark per 100ms with around 9 spikes in 10 seconds
52 * Congestion Window: Oscillating between around 400 segments and 800 segments
53 * TCP RTT: Below 85ms with frequent spikes up to 95ms (more than the previous
54 * configuration) Queue Delay-n0: Below 5ms with frequent spikes
55 */
56
57/** Network topology - For Configuration 3, 4
58 *
59 * 1Gbps, 1ms 100Mbps, 1us 1Gbps, 1us
60 * n0 ---------- n2 ---------------- n3 --------------n4
61 *
62 * Configuration 3: single flow DCTCP with ECN ECT(0), CE_threshold = 1ms, base RTT of 1ms
63 *
64 * Expected Result:
65 * Throughput: Fixed just below 100Mbps.
66 * Ping RTT: Oscillating below 1.5ms
67 * Drop frequency: There should not be any drops
68 * Length: Very frequently oscillating between 0.5ms and 1ms with frequent spikes up
69 * to 1.2ms Mark Frequency: Around 160 marks per 100ms Congestion Window: Very frequently
70 * oscillating at a low value (below 25) TCP RTT: Very frequently oscillating, below 5ms
71 * Queue Delay-n0: Very frequently oscillating between 0.5ms and 1ms with spikes up to 1.2ms
72 *
73 * Configuration 4: single flow DCTCP with ECN ECT(1), L4S mode enabled on FqCoDel, base RTT of 1ms
74 *
75 * Expected Result:
76 * Throughput: Fixed just below 100Mbps.
77 * Ping RTT: Oscillating below 1.5ms
78 * Drop frequency: There should not be any drops
79 * Length: Very frequently oscillating between 0.5ms and 1ms with frequent spikes up
80 * to 1.2ms Mark Frequency: Around 160 marks per 100ms Congestion Window: Very frequently
81 * oscillating at a low value (below 25) TCP RTT: Very frequently oscillating, below 5ms
82 * Queue Delay-n0: Very frequently oscillating between 0.5ms and 1ms with spikes up to 1.2ms
83 */
84
85/** Network topology - For Configuration 5, 6
86 *
87 * 1Gbps, 40ms 1Gbps, 1us
88 * n0--------------| |---------------n4
89 * | 100Mbps, 1us |
90 * n2------------------n3
91 * 1Gbps, 40ms | | 1Gbps, 1us
92 * n1--------------| |---------------n5
93 *
94 * Configuration 5: Two flows TCP BIC without ECN, base RTT of 80 ms
95 *
96 * Expected Result:
97 * Throughput-n0: Oscillating around 100 before second flow starts, and after that,
98 * oscillating around 50. Throughput-n1: Oscillating around 50. Ping RTT: Oscillating and
99 * reaching around 80.5ms Drop frequency: Around 1 drop per 100ms, more spikes than the single
100 * flow Length: Around 5ms with spikes reaching 10ms Mark Frequency: There
101 * should not be any marks Congestion Window-n0: Oscillating between 800 segments and 600 segments
102 * before second flow starts, after that oscillating around 300 segments Congestion Window-n0:
103 * Oscillating around 300 segments TCP RTT-n0: Below 85ms with spikes reaching 90ms before
104 * second flow starts, and after that below 85ms with spikes reaching 90ms TCP RTT-n0: Below 85ms
105 * with spikes reaching 90ms Queue Delay-n0: Below 5ms with spikes reaching 10ms before second
106 * flow starts and after that below 5ms with spikes up to 15ms. Queue Delay-n0: Below 5ms with
107 * spikes up to 15ms.
108 *
109 * Configuration 6: Two flows TCP BIC with ECN, base RTT of 80 ms
110 *
111 * Expected Result:
112 *
113 * Throughput-n0: Oscillating around 100 before second flow starts, and after that,
114 * oscillating around 50. Throughput-n1: Oscillating around 50. Ping RTT: Oscillating and
115 * reaching around 80.5ms Drop frequency: There should not be any drops Mark Frequency: Around
116 * 1 drop per 100ms, more spikes than the single flow Length: Around 5ms with spikes
117 * reaching 15ms Congestion Window-n0: Oscillating between 800 segments and 600 segments before
118 * second flow starts, after that oscillating around 300 segments Congestion Window-n0: Oscillating
119 * around 300 segments TCP RTT-n0: Below 85ms with spikes reaching 95ms before second flow
120 * starts, and after that below 85ms with spikes reaching 100ms TCP RTT-n0: Below 85ms
121 * with spikes reaching 100ms Queue Delay-n0: Below 5ms with spikes reaching 15ms before
122 * second flow starts and after that below 5ms with spikes up to 20ms. Queue Delay-n0: Below
123 * 5ms with spikes up to 20ms.
124 */
125
126/**Network topology - For Configuration 7, 8
127 *
128 * 1Gbps, 1ms 1Gbps, 1us
129 * n0--------------| |---------------n4
130 * | 100Mbps, 1us |
131 * n2------------------n3
132 * 1Gbps, 1ms | | 1Gbps, 1us
133 * n1--------------| |---------------n5
134 *
135 * Configuration 7: Two flows DCTCP with ECN ECT(0), CE_threshold = 1ms, base RTT of 1ms
136 *
137 * Expected Result:
138 * Throughput-n0: Fixed around 100 before second flow starts, and after that, fixed
139 * around 50. Throughput-n1: Fixed around 50. Ping RTT: Oscillating and reaching
140 * around 1.5ms Drop frequency: There should not be any drops Length: Around
141 * 1ms. Mark Frequency: Oscillating little above 150 marks per 100ms before second flow start,
142 * and after that oscillating little below 250 marks per 100ms
143 * Congestion Window-n0: Oscillating around 20 segments before second flow starts
144 * then oscillating around 11 segments
145 * Congestion Window-n1: Oscillating around 11 segments
146 * TCP RTT-n0: Oscillating between 2ms and 5ms before seconds flow starts and after that
147 * oscillating between 3ms and 5ms
148 * TCP RTT-n1: Oscillating between 3ms and 5ms
149 * Queue Delay-n0: Oscillating frequently below 1ms before second flow starts and after that
150 * just below 1.4ms Queue Delay-n1: Oscillating frequently between 0.4ms and 1.4ms
151 *
152 * Configuration 8: Two flows DCTCP with ECN ECT(1), L4S mode enabled on FqCoDel, base RTT of 1ms
153 *
154 * Throughput-n0: Fixed around 100 before second flow starts, and after that, fixed
155 * around 50. Throughput-n1: Fixed around 50. Ping RTT: Oscillating and reaching
156 * around 1.5ms Drop frequency: There should not be any drops Length: Around
157 * 1ms. Mark Frequency: Oscillating little above 150 marks per 100ms before second flow start,
158 * and after that oscillating little below 250 marks per 100ms
159 * Congestion Window-n0: Oscillating around 20 segments before second flow starts
160 * then oscillating around 11 segments
161 * Congestion Window-n1: Oscillating around 11 segments
162 * TCP RTT-n0: Oscillating between 2ms and 5ms before seconds flow starts and after that
163 * oscillating between 3ms and 5ms
164 * TCP RTT-n1: Oscillating between 3ms and 5ms
165 * Queue Delay-n0: Oscillating frequently below 1ms before second flow starts and after that
166 * just below 1.4ms Queue Delay-n1: Oscillating frequently between 0.4ms and 1.4ms
167 */
168
169/**Network topology - For Configuration 9
170 *
171 * 1Gbps, 1ms 1Gbps, 1us
172 * n0--------------| |---------------n4
173 * | 100Mbps, 1us |
174 * n2------------------n3
175 * 1Gbps, 80ms | | 1Gbps, 1us
176 * n1--------------| |---------------n5
177 *
178 * Configuration 9: One TCP BIC (n0) with base RTT of 80 ms, one DCTCP (n1) with ECN ECT(1), L4S
179 * mode enabled, base RTT 1ms
180 *
181 * Throughput-n0: Oscillating below 100Mbps before second flow starts, and after that,
182 * oscillating around 50Mbps. Throughput-n1: Oscillating around 50Mbps. Ping RTT: Oscillating
183 * and reaching around 80.5ms Drop frequency: There should not be any drops Length: Around 5ms
184 * with frequent spikes above 10ms before second flow starts and after that spikes below 10ms. Mark
185 * Frequency: Oscillating 1 marks per 100ms before second flow start, and after that
186 * oscillating below 200 marks per 100ms Congestion Window-n0: Oscillating around 600 segments
187 * before second flow starts then oscillating around 300 segments Congestion Window-n1: Oscillating
188 * around 300 segments TCP RTT-n0: Around 85ms with spikes reaching around 95ms before
189 * second flow starts and after that around 85ms with spikes reaching 100ms TCP RTT-n1: Around 85ms
190 * with spikes reaching 100ms Queue Delay-n0: Around 5ms with spikes above 10ms before second
191 * flow starts and nearly the same after that too. Queue Delay-n1: Oscillating frequently
192 * between 0.4ms and 1.4ms with spikes reaching 3ms.
193 *
194 */
195
196/**
197 * clients and servers are configured for ICMP measurements and TCP throughput
198 * and latency measurements in the downstream direction
199 *
200 * Depending on the scenario, the middlebox and endpoints will be
201 * configured differently. Scenarios can be configured explicitly by
202 * scenario Numbers as well as by combinations of input arguments.
203 *
204 * All link rates are enforced by a point-to-point (P2P) ns-3 model with full
205 * duplex operation. The link rate and delays are enforced by this model
206 * (in contrast to netem and shaping in the testbed). Dynamic queue limits
207 * (BQL) are enabled to allow for queueing to occur at the priority queue layer;
208 *
209 * By default, the ns-3 FQ-CoDel model is installed on all interfaces.
210 *
211 * The ns-3 FQ-CoDel model uses ns-3 defaults:
212 * - 100ms interval
213 * - 5ms target
214 * - drop batch size of 64 packets
215 * - minbytes of 1500
216 *
217 * Default simulation time is 70 sec. For single flow experiments, the flow is
218 * started at simulation time 5 sec; if a second flow is used, it starts
219 * at 15 sec.
220 *
221 * ping frequency is set at 100ms
222 * Note that pings may miss the peak of queue buildups for short-lived flows;
223 * hence, we trace also the queue length expressed in units of time at
224 * the bottleneck link rate.
225 *
226 * A command-line option to enable CE Threshold is provided
227 *
228 * Results will be available in ns-3-dev/results/FqCoDel-L4S consisting of 14 .dat files
229 *
230 * Measure:
231 * - ping RTT
232 * - TCP RTT estimate
233 * - TCP throughput
234 * - Queue delay
235 *
236 * IPv4 addressing
237 * ----------------------------
238 * pingServer 10.1.1.2 (ping source)
239 * n0Server 10.1.2.2 (data sender)
240 * n1Server 10.1.3.2 (data sender)
241 * pingClient 192.168.1.2
242 * n4Client 192.168.2.2
243 * n5Client 192.168.3.2
244 *
245 * Program options
246 * ---------------
247 * --n0TcpType: First TCP type (bic, dctcp, or reno) [bic]
248 * --n1TcpType: Second TCP type (cubic, dctcp, or reno) []
249 * --scenarioNum: Scenario number from the scenarios available in the file (1-9) [0]
250 * --bottleneckQueueType: n2 queue type (fq or codel) [fq]
251 * --baseRtt: base RTT [80ms]
252 * --useCeThreshold: use CE threshold [false]
253 * --useEcn: use ECN [true]
254 * --ceThreshold: CE threshold [1ms]
255 * --bottleneckRate data rate of bottleneck [100Mbps]
256 * --linkrate: data rate of edge link to bottleneck link [1Gbps]
257 * --stopTime: simulation stop time [70s]
258 * --enablePcap: enable Pcap [false]
259 * (additional arguments to control trace names)
260 **/
261
262#include "ns3/applications-module.h"
263#include "ns3/core-module.h"
264#include "ns3/flow-monitor-helper.h"
265#include "ns3/internet-apps-module.h"
266#include "ns3/internet-module.h"
267#include "ns3/network-module.h"
268#include "ns3/point-to-point-module.h"
269#include "ns3/traffic-control-module.h"
270
271using namespace ns3;
272
273NS_LOG_COMPONENT_DEFINE("FqCoDelL4SExample");
274
277
282
283void
284TraceN0Cwnd(std::ofstream* ofStream, uint32_t oldCwnd, uint32_t newCwnd)
285{
286 // TCP segment size is configured below to be 1448 bytes
287 // so that we can report cwnd in units of segments
288 *ofStream << Simulator::Now().GetSeconds() << " " << static_cast<double>(newCwnd) / 1448
289 << std::endl;
290}
291
292void
293TraceN1Cwnd(std::ofstream* ofStream, uint32_t oldCwnd, uint32_t newCwnd)
294{
295 // TCP segment size is configured below to be 1448 bytes
296 // so that we can report cwnd in units of segments
297 *ofStream << Simulator::Now().GetSeconds() << " " << static_cast<double>(newCwnd) / 1448
298 << std::endl;
299}
300
301void
302TraceN0Rtt(std::ofstream* ofStream, Time oldRtt, Time newRtt)
303{
304 *ofStream << Simulator::Now().GetSeconds() << " " << newRtt.GetSeconds() * 1000 << std::endl;
305}
306
307void
308TraceN1Rtt(std::ofstream* ofStream, Time oldRtt, Time newRtt)
309{
310 *ofStream << Simulator::Now().GetSeconds() << " " << newRtt.GetSeconds() * 1000 << std::endl;
311}
312
313void
314TracePingRtt(std::ofstream* ofStream, uint16_t seqNo, Time rtt)
315{
316 *ofStream << Simulator::Now().GetSeconds() << " " << seqNo << " " << rtt.GetSeconds() * 1000
317 << std::endl;
318}
319
320void
321TraceN0Rx(Ptr<const Packet> packet, const Address& address)
322{
323 g_n0BytesReceived += packet->GetSize();
324}
325
326void
327TraceN1Rx(Ptr<const Packet> packet, const Address& address)
328{
329 g_n1BytesReceived += packet->GetSize();
330}
331
332void
333TraceDrop(std::ofstream* ofStream, Ptr<const QueueDiscItem> item)
334{
335 *ofStream << Simulator::Now().GetSeconds() << " " << std::hex << item->Hash() << std::endl;
337}
338
339void
340TraceMark(std::ofstream* ofStream, Ptr<const QueueDiscItem> item, const char* reason)
341{
342 *ofStream << Simulator::Now().GetSeconds() << " " << std::hex << item->Hash() << std::endl;
344}
345
346void
347TraceQueueLength(std::ofstream* ofStream, DataRate linkRate, uint32_t oldVal, uint32_t newVal)
348{
349 // output in units of ms
350 *ofStream << Simulator::Now().GetSeconds() << " " << std::fixed
351 << static_cast<double>(newVal * 8) / (linkRate.GetBitRate() / 1000) << std::endl;
352}
353
354void
355TraceDropsFrequency(std::ofstream* ofStream, Time dropsSamplingInterval)
356{
357 *ofStream << Simulator::Now().GetSeconds() << " " << g_dropsObserved << std::endl;
358 g_dropsObserved = 0;
359 Simulator::Schedule(dropsSamplingInterval,
361 ofStream,
362 dropsSamplingInterval);
363}
364
365void
366TraceMarksFrequency(std::ofstream* ofStream, Time marksSamplingInterval)
367{
368 *ofStream << Simulator::Now().GetSeconds() << " " << g_marksObserved << std::endl;
369 g_marksObserved = 0;
370 Simulator::Schedule(marksSamplingInterval,
372 ofStream,
373 marksSamplingInterval);
374}
375
376void
377TraceN0Throughput(std::ofstream* ofStream, Time throughputInterval)
378{
379 *ofStream << Simulator::Now().GetSeconds() << " "
380 << g_n0BytesReceived * 8 / throughputInterval.GetSeconds() / 1e6 << std::endl;
382 Simulator::Schedule(throughputInterval, &TraceN0Throughput, ofStream, throughputInterval);
383}
384
385void
386TraceN1Throughput(std::ofstream* ofStream, Time throughputInterval)
387{
388 *ofStream << Simulator::Now().GetSeconds() << " "
389 << g_n1BytesReceived * 8 / throughputInterval.GetSeconds() / 1e6 << std::endl;
391 Simulator::Schedule(throughputInterval, &TraceN1Throughput, ofStream, throughputInterval);
392}
393
394void
395ScheduleN0TcpCwndTraceConnection(std::ofstream* ofStream)
396{
397 Config::ConnectWithoutContext("/NodeList/1/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow",
398 MakeBoundCallback(&TraceN0Cwnd, ofStream));
399}
400
401void
402ScheduleN0TcpRttTraceConnection(std::ofstream* ofStream)
403{
404 Config::ConnectWithoutContext("/NodeList/1/$ns3::TcpL4Protocol/SocketList/0/RTT",
405 MakeBoundCallback(&TraceN0Rtt, ofStream));
406}
407
408void
410{
411 Config::ConnectWithoutContext("/NodeList/6/ApplicationList/*/$ns3::PacketSink/Rx",
413}
414
415void
416ScheduleN1TcpCwndTraceConnection(std::ofstream* ofStream)
417{
418 Config::ConnectWithoutContext("/NodeList/2/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow",
419 MakeBoundCallback(&TraceN1Cwnd, ofStream));
420}
421
422void
423ScheduleN1TcpRttTraceConnection(std::ofstream* ofStream)
424{
425 Config::ConnectWithoutContext("/NodeList/2/$ns3::TcpL4Protocol/SocketList/0/RTT",
426 MakeBoundCallback(&TraceN1Rtt, ofStream));
427}
428
429void
431{
432 Config::ConnectWithoutContext("/NodeList/7/ApplicationList/*/$ns3::PacketSink/Rx",
434}
435
436static void
437PacketDequeue(std::ofstream* n0OfStream, std::ofstream* n1OfStream, Ptr<const QueueDiscItem> item)
438{
439 Ptr<Packet> p = item->GetPacket();
442 Ipv4Address address = iqdi->GetHeader().GetDestination();
443 Time qDelay = Simulator::Now() - item->GetTimeStamp();
444 if (address == "192.168.2.2")
445 {
446 *n0OfStream << Simulator::Now().GetSeconds() << " " << qDelay.GetMicroSeconds() / 1000.0
447 << std::endl;
448 }
449 else if (address == "192.168.3.2")
450 {
451 *n1OfStream << Simulator::Now().GetSeconds() << " " << qDelay.GetMicroSeconds() / 1000.0
452 << std::endl;
453 }
454}
455
456int
457main(int argc, char* argv[])
458{
459 ////////////////////////////////////////////////////////////
460 // variables not configured at command line //
461 ////////////////////////////////////////////////////////////
462 Time stopTime = Seconds(70);
463 Time baseRtt = MilliSeconds(80);
464 uint32_t pingSize = 100; // bytes
465 Time pingInterval = MilliSeconds(100);
466 Time marksSamplingInterval = MilliSeconds(100);
467 Time throughputSamplingInterval = MilliSeconds(200);
468 DataRate bottleneckRate("100Mbps");
469
470 std::string dir = "results/FqCoDel-L4S/";
471 std::string dirToSave = "mkdir -p " + dir;
472 if (system(dirToSave.c_str()) == -1)
473 {
474 exit(1);
475 }
476
477 std::string pingTraceFile = dir + "ping.dat";
478 std::string n0TcpRttTraceFile = dir + "n0-tcp-rtt.dat";
479 std::string n0TcpCwndTraceFile = dir + "n0-tcp-cwnd.dat";
480 std::string n0TcpThroughputTraceFile = dir + "n0-tcp-throughput.dat";
481 std::string n1TcpRttTraceFile = dir + "n1-tcp-rtt.dat";
482 std::string n1TcpCwndTraceFile = dir + "n1-tcp-cwnd.dat";
483 std::string n1TcpThroughputTraceFile = dir + "n1-tcp-throughput.dat";
484 std::string dropTraceFile = dir + "drops.dat";
485 std::string dropsFrequencyTraceFile = dir + "drops-frequency.dat";
486 std::string lengthTraceFile = dir + "length.dat";
487 std::string markTraceFile = dir + "mark.dat";
488 std::string marksFrequencyTraceFile = dir + "marks-frequency.dat";
489 std::string queueDelayN0TraceFile = dir + "queue-delay-n0.dat";
490 std::string queueDelayN1TraceFile = dir + "queue-delay-n1.dat";
491
492 ////////////////////////////////////////////////////////////
493 // variables configured at command line //
494 ////////////////////////////////////////////////////////////
495 bool enablePcap = false;
496 bool useCeThreshold = false;
497 Time ceThreshold = MilliSeconds(1);
498 std::string n0TcpType = "bic";
499 std::string n1TcpType = "";
500 bool enableN1Tcp = false;
501 bool useEcn = true;
502 std::string queueType = "fq";
503 std::string linkDataRate = "1Gbps";
504 uint32_t scenarioNum = 0;
505
506 ////////////////////////////////////////////////////////////
507 // Override ns-3 defaults //
508 ////////////////////////////////////////////////////////////
509 Config::SetDefault("ns3::TcpSocket::SegmentSize", UintegerValue(1448));
510 // Increase default buffer sizes to improve throughput over long delay paths
511 Config::SetDefault("ns3::TcpSocket::SndBufSize", UintegerValue(8192000));
512 Config::SetDefault("ns3::TcpSocket::RcvBufSize", UintegerValue(8192000));
513 Config::SetDefault("ns3::TcpSocket::InitialCwnd", UintegerValue(10));
514 Config::SetDefault("ns3::TcpL4Protocol::RecoveryType",
516
517 ////////////////////////////////////////////////////////////
518 // command-line argument parsing //
519 ////////////////////////////////////////////////////////////
521 cmd.AddValue("n0TcpType", "n0 TCP type (bic, dctcp, or reno)", n0TcpType);
522 cmd.AddValue("n1TcpType", "n1 TCP type (bic, dctcp, or reno)", n1TcpType);
523 cmd.AddValue("scenarioNum",
524 "Scenario number from the scenarios available in the file (1-9)",
525 scenarioNum);
526 cmd.AddValue("bottleneckQueueType", "n2 queue type (fq or codel)", queueType);
527 cmd.AddValue("baseRtt", "base RTT", baseRtt);
528 cmd.AddValue("useCeThreshold", "use CE Threshold", useCeThreshold);
529 cmd.AddValue("useEcn", "use ECN", useEcn);
530 cmd.AddValue("ceThreshold", "CoDel CE threshold", ceThreshold);
531 cmd.AddValue("bottleneckRate", "data rate of bottleneck", bottleneckRate);
532 cmd.AddValue("linkRate", "data rate of edge link", linkDataRate);
533 cmd.AddValue("stopTime", "simulation stop time", stopTime);
534 cmd.AddValue("enablePcap", "enable Pcap", enablePcap);
535 cmd.AddValue("pingTraceFile", "filename for ping tracing", pingTraceFile);
536 cmd.AddValue("n0TcpRttTraceFile", "filename for n0 rtt tracing", n0TcpRttTraceFile);
537 cmd.AddValue("n0TcpCwndTraceFile", "filename for n0 cwnd tracing", n0TcpCwndTraceFile);
538 cmd.AddValue("n0TcpThroughputTraceFile",
539 "filename for n0 throughput tracing",
540 n0TcpThroughputTraceFile);
541 cmd.AddValue("n1TcpRttTraceFile", "filename for n1 rtt tracing", n1TcpRttTraceFile);
542 cmd.AddValue("n1TcpCwndTraceFile", "filename for n1 cwnd tracing", n1TcpCwndTraceFile);
543 cmd.AddValue("n1TcpThroughputTraceFile",
544 "filename for n1 throughput tracing",
545 n1TcpThroughputTraceFile);
546 cmd.AddValue("dropTraceFile", "filename for n2 drops tracing", dropTraceFile);
547 cmd.AddValue("dropsFrequencyTraceFile",
548 "filename for n2 drop frequency tracing",
549 dropsFrequencyTraceFile);
550 cmd.AddValue("lengthTraceFile", "filename for n2 queue length tracing", lengthTraceFile);
551 cmd.AddValue("markTraceFile", "filename for n2 mark tracing", markTraceFile);
552 cmd.AddValue("marksFrequencyTraceFile",
553 "filename for n2 mark frequency tracing",
554 marksFrequencyTraceFile);
555 cmd.AddValue("queueDelayN0TraceFile",
556 "filename for n0 queue delay tracing",
557 queueDelayN0TraceFile);
558 cmd.AddValue("queueDelayN1TraceFile",
559 "filename for n1 queue delay tracing",
560 queueDelayN1TraceFile);
561 cmd.Parse(argc, argv);
562 Time oneWayDelay = baseRtt / 2;
563 TypeId n0TcpTypeId;
564 TypeId n1TcpTypeId;
565 TypeId queueTypeId;
566 if (!scenarioNum)
567 {
568 if (useEcn)
569 {
570 Config::SetDefault("ns3::TcpSocketBase::UseEcn", StringValue("On"));
571 }
572
573 if (n0TcpType == "reno")
574 {
575 n0TcpTypeId = TcpNewReno::GetTypeId();
576 }
577 else if (n0TcpType == "bic")
578 {
579 n0TcpTypeId = TcpBic::GetTypeId();
580 }
581 else if (n0TcpType == "dctcp")
582 {
583 n0TcpTypeId = TcpDctcp::GetTypeId();
584 }
585 else
586 {
587 NS_FATAL_ERROR("Fatal error: tcp unsupported");
588 }
589
590 if (n1TcpType == "reno")
591 {
592 enableN1Tcp = true;
593 n1TcpTypeId = TcpNewReno::GetTypeId();
594 }
595 else if (n1TcpType == "bic")
596 {
597 enableN1Tcp = true;
598 n1TcpTypeId = TcpBic::GetTypeId();
599 }
600 else if (n1TcpType == "dctcp")
601 {
602 enableN1Tcp = true;
603 n1TcpTypeId = TypeId::LookupByName("ns3::TcpDctcp");
604 }
605 else if (n1TcpType.empty())
606 {
607 NS_LOG_DEBUG("No N1 TCP selected");
608 }
609 else
610 {
611 NS_FATAL_ERROR("Fatal error: tcp unsupported");
612 }
613
614 if (queueType == "fq")
615 {
616 queueTypeId = FqCoDelQueueDisc::GetTypeId();
617 }
618 else if (queueType == "codel")
619 {
620 queueTypeId = CoDelQueueDisc::GetTypeId();
621 }
622 else
623 {
624 NS_FATAL_ERROR("Fatal error: queueType unsupported");
625 }
626 if (useCeThreshold)
627 {
628 Config::SetDefault("ns3::FqCoDelQueueDisc::CeThreshold", TimeValue(ceThreshold));
629 }
630 }
631 else if (scenarioNum == 1 || scenarioNum == 2 || scenarioNum == 5 || scenarioNum == 6)
632 {
633 if (scenarioNum == 2 || scenarioNum == 6)
634 {
635 Config::SetDefault("ns3::TcpSocketBase::UseEcn", StringValue("On"));
636 }
637 n0TcpTypeId = TcpBic::GetTypeId();
638 if (scenarioNum == 5 || scenarioNum == 6)
639 {
640 enableN1Tcp = true;
641 n1TcpTypeId = TcpBic::GetTypeId();
642 }
643 queueTypeId = FqCoDelQueueDisc::GetTypeId();
644 }
645 else if (scenarioNum == 3 || scenarioNum == 4 || scenarioNum == 7 || scenarioNum == 8 ||
646 scenarioNum == 9)
647 {
648 Config::SetDefault("ns3::TcpSocketBase::UseEcn", StringValue("On"));
649 n0TcpTypeId = TcpDctcp::GetTypeId();
650 queueTypeId = FqCoDelQueueDisc::GetTypeId();
651 oneWayDelay = MicroSeconds(500);
652 Config::SetDefault("ns3::FqCoDelQueueDisc::CeThreshold", TimeValue(MilliSeconds(1)));
653 if (scenarioNum == 9)
654 {
655 n0TcpTypeId = TcpBic::GetTypeId();
656 // For TCP Bic base RTT is 80 and base RTT for dctcp is set to 1 while setting delay for
657 // p2p devices
658 oneWayDelay = MilliSeconds(40);
659 }
660 if (scenarioNum == 4 || scenarioNum == 8 || scenarioNum == 9)
661 {
662 Config::SetDefault("ns3::FqCoDelQueueDisc::UseL4s", BooleanValue(true));
663 Config::SetDefault("ns3::TcpDctcp::UseEct0", BooleanValue(false));
664 }
665 if (scenarioNum == 7 || scenarioNum == 8 || scenarioNum == 9)
666 {
667 enableN1Tcp = true;
668 n1TcpTypeId = TcpDctcp::GetTypeId();
669 }
670 }
671 else
672 {
673 NS_FATAL_ERROR("Fatal error: scenario unavailable");
674 }
675
676 std::ofstream pingOfStream;
677 pingOfStream.open(pingTraceFile, std::ofstream::out);
678 std::ofstream n0TcpRttOfStream;
679 n0TcpRttOfStream.open(n0TcpRttTraceFile, std::ofstream::out);
680 std::ofstream n0TcpCwndOfStream;
681 n0TcpCwndOfStream.open(n0TcpCwndTraceFile, std::ofstream::out);
682 std::ofstream n0TcpThroughputOfStream;
683 n0TcpThroughputOfStream.open(n0TcpThroughputTraceFile, std::ofstream::out);
684 std::ofstream n1TcpRttOfStream;
685 n1TcpRttOfStream.open(n1TcpRttTraceFile, std::ofstream::out);
686 std::ofstream n1TcpCwndOfStream;
687 n1TcpCwndOfStream.open(n1TcpCwndTraceFile, std::ofstream::out);
688 std::ofstream n1TcpThroughputOfStream;
689 n1TcpThroughputOfStream.open(n1TcpThroughputTraceFile, std::ofstream::out);
690
691 // Queue disc files
692 std::ofstream dropOfStream;
693 dropOfStream.open(dropTraceFile, std::ofstream::out);
694 std::ofstream markOfStream;
695 markOfStream.open(markTraceFile, std::ofstream::out);
696 std::ofstream dropsFrequencyOfStream;
697 dropsFrequencyOfStream.open(dropsFrequencyTraceFile, std::ofstream::out);
698 std::ofstream marksFrequencyOfStream;
699 marksFrequencyOfStream.open(marksFrequencyTraceFile, std::ofstream::out);
700 std::ofstream lengthOfStream;
701 lengthOfStream.open(lengthTraceFile, std::ofstream::out);
702 std::ofstream queueDelayN0OfStream;
703 queueDelayN0OfStream.open(queueDelayN0TraceFile, std::ofstream::out);
704 std::ofstream queueDelayN1OfStream;
705 queueDelayN1OfStream.open(queueDelayN1TraceFile, std::ofstream::out);
706
707 ////////////////////////////////////////////////////////////
708 // scenario setup //
709 ////////////////////////////////////////////////////////////
710 Ptr<Node> pingServer = CreateObject<Node>();
711 Ptr<Node> n0Server = CreateObject<Node>();
712 Ptr<Node> n1Server = CreateObject<Node>();
715 Ptr<Node> pingClient = CreateObject<Node>();
716 Ptr<Node> n4Client = CreateObject<Node>();
717 Ptr<Node> n5Client = CreateObject<Node>();
718
719 // Device containers
720 NetDeviceContainer pingServerDevices;
721 NetDeviceContainer n0ServerDevices;
722 NetDeviceContainer n1ServerDevices;
723 NetDeviceContainer n2n3Devices;
724 NetDeviceContainer pingClientDevices;
725 NetDeviceContainer n4ClientDevices;
726 NetDeviceContainer n5ClientDevices;
727
729 p2p.SetQueue("ns3::DropTailQueue", "MaxSize", QueueSizeValue(QueueSize("3p")));
730 p2p.SetDeviceAttribute("DataRate", DataRateValue(DataRate(linkDataRate)));
731 // Add delay only on the server links
732 p2p.SetChannelAttribute("Delay", TimeValue(oneWayDelay));
733 pingServerDevices = p2p.Install(n2, pingServer);
734 n0ServerDevices = p2p.Install(n2, n0Server);
735
736 // In scenario 9, base RTT of n1server (dctcp) is 1ms
737 if (scenarioNum == 9)
738 {
739 p2p.SetChannelAttribute("Delay", TimeValue(MicroSeconds(500)));
740 }
741 n1ServerDevices = p2p.Install(n2, n1Server);
742 p2p.SetChannelAttribute("Delay", TimeValue(MicroSeconds(1)));
743 n2n3Devices = p2p.Install(n2, n3);
744 pingClientDevices = p2p.Install(n3, pingClient);
745 n4ClientDevices = p2p.Install(n3, n4Client);
746 n5ClientDevices = p2p.Install(n3, n5Client);
747 Ptr<PointToPointNetDevice> p = n2n3Devices.Get(0)->GetObject<PointToPointNetDevice>();
748 p->SetAttribute("DataRate", DataRateValue(bottleneckRate));
749
750 InternetStackHelper stackHelper;
751 stackHelper.InstallAll();
752
753 // Set the per-node TCP type here
754 Ptr<TcpL4Protocol> proto;
755 proto = n4Client->GetObject<TcpL4Protocol>();
756 proto->SetAttribute("SocketType", TypeIdValue(n0TcpTypeId));
757 proto = n0Server->GetObject<TcpL4Protocol>();
758 proto->SetAttribute("SocketType", TypeIdValue(n0TcpTypeId));
759 if (enableN1Tcp)
760 {
761 proto = n5Client->GetObject<TcpL4Protocol>();
762 proto->SetAttribute("SocketType", TypeIdValue(n1TcpTypeId));
763 proto = n1Server->GetObject<TcpL4Protocol>();
764 proto->SetAttribute("SocketType", TypeIdValue(n1TcpTypeId));
765 }
766
767 // InternetStackHelper will install a base TrafficControlLayer on the node,
768 // but the Ipv4AddressHelper below will install the default FqCoDelQueueDisc
769 // on all single device nodes. The below code overrides the configuration
770 // that is normally done by the Ipv4AddressHelper::Install() method by
771 // instead explicitly configuring the queue discs we want on each device.
773 tchFq.SetRootQueueDisc("ns3::FqCoDelQueueDisc");
774 tchFq.SetQueueLimits("ns3::DynamicQueueLimits", "HoldTime", StringValue("1ms"));
775 tchFq.Install(pingServerDevices);
776 tchFq.Install(n0ServerDevices);
777 tchFq.Install(n1ServerDevices);
778 tchFq.Install(n2n3Devices.Get(1)); // n2 queue for bottleneck link
779 tchFq.Install(pingClientDevices);
780 tchFq.Install(n4ClientDevices);
781 tchFq.Install(n5ClientDevices);
783 tchN2.SetRootQueueDisc(queueTypeId.GetName());
784 tchN2.SetQueueLimits("ns3::DynamicQueueLimits", "HoldTime", StringValue("1000ms"));
785 tchN2.Install(n2n3Devices.Get(0));
786
788 ipv4.SetBase("10.1.1.0", "255.255.255.0");
789 Ipv4InterfaceContainer pingServerIfaces = ipv4.Assign(pingServerDevices);
790 ipv4.SetBase("10.1.2.0", "255.255.255.0");
791 Ipv4InterfaceContainer n0ServerIfaces = ipv4.Assign(n0ServerDevices);
792 ipv4.SetBase("10.1.3.0", "255.255.255.0");
793 Ipv4InterfaceContainer secondServerIfaces = ipv4.Assign(n1ServerDevices);
794 ipv4.SetBase("172.16.1.0", "255.255.255.0");
795 Ipv4InterfaceContainer n2n3Ifaces = ipv4.Assign(n2n3Devices);
796 ipv4.SetBase("192.168.1.0", "255.255.255.0");
797 Ipv4InterfaceContainer pingClientIfaces = ipv4.Assign(pingClientDevices);
798 ipv4.SetBase("192.168.2.0", "255.255.255.0");
799 Ipv4InterfaceContainer n4ClientIfaces = ipv4.Assign(n4ClientDevices);
800 ipv4.SetBase("192.168.3.0", "255.255.255.0");
801 Ipv4InterfaceContainer n5ClientIfaces = ipv4.Assign(n5ClientDevices);
802
804
805 ////////////////////////////////////////////////////////////
806 // application setup //
807 ////////////////////////////////////////////////////////////
808
809 PingHelper pingHelper(Ipv4Address("192.168.1.2"));
810 pingHelper.SetAttribute("Interval", TimeValue(pingInterval));
811 pingHelper.SetAttribute("Size", UintegerValue(pingSize));
812 ApplicationContainer pingContainer = pingHelper.Install(pingServer);
813 Ptr<Ping> ping = pingContainer.Get(0)->GetObject<Ping>();
814 ping->TraceConnectWithoutContext("Rtt", MakeBoundCallback(&TracePingRtt, &pingOfStream));
815 pingContainer.Start(Seconds(1));
816 pingContainer.Stop(stopTime - Seconds(1));
817
818 BulkSendHelper tcp("ns3::TcpSocketFactory", Address());
819 // set to large value: e.g. 1000 Mb/s for 60 seconds = 7500000000 bytes
820 tcp.SetAttribute("MaxBytes", UintegerValue(7500000000));
821 // Configure n4/n0 TCP client/server pair
822 uint16_t n4Port = 5000;
824 InetSocketAddress n0DestAddress(n4ClientIfaces.GetAddress(1), n4Port);
825 tcp.SetAttribute("Remote", AddressValue(n0DestAddress));
826 n0App = tcp.Install(n0Server);
827 n0App.Start(Seconds(5));
828 n0App.Stop(stopTime - Seconds(1));
829
830 Address n4SinkAddress(InetSocketAddress(Ipv4Address::GetAny(), n4Port));
831 PacketSinkHelper n4SinkHelper("ns3::TcpSocketFactory", n4SinkAddress);
832 ApplicationContainer n4SinkApp;
833 n4SinkApp = n4SinkHelper.Install(n4Client);
834 n4SinkApp.Start(Seconds(5));
835 n4SinkApp.Stop(stopTime - MilliSeconds(500));
836
837 // Configure second TCP client/server pair
838 if (enableN1Tcp)
839 {
840 uint16_t n5Port = 5000;
841 ApplicationContainer secondApp;
842 InetSocketAddress n1DestAddress(n5ClientIfaces.GetAddress(1), n5Port);
843 tcp.SetAttribute("Remote", AddressValue(n1DestAddress));
844 secondApp = tcp.Install(n1Server);
845 secondApp.Start(Seconds(15));
846 secondApp.Stop(stopTime - Seconds(1));
847
848 Address n5SinkAddress(InetSocketAddress(Ipv4Address::GetAny(), n5Port));
849 PacketSinkHelper n5SinkHelper("ns3::TcpSocketFactory", n5SinkAddress);
850 ApplicationContainer n5SinkApp;
851 n5SinkApp = n5SinkHelper.Install(n5Client);
852 n5SinkApp.Start(Seconds(15));
853 n5SinkApp.Stop(stopTime - MilliSeconds(500));
854 }
855
856 // Setup traces that can be hooked now
859 tc = n2n3Devices.Get(0)->GetNode()->GetObject<TrafficControlLayer>();
860 qd = tc->GetRootQueueDiscOnDevice(n2n3Devices.Get(0));
861 qd->TraceConnectWithoutContext("Drop", MakeBoundCallback(&TraceDrop, &dropOfStream));
862 qd->TraceConnectWithoutContext("Mark", MakeBoundCallback(&TraceMark, &markOfStream));
864 "BytesInQueue",
865 MakeBoundCallback(&TraceQueueLength, &lengthOfStream, bottleneckRate));
867 "Dequeue",
868 MakeBoundCallback(&PacketDequeue, &queueDelayN0OfStream, &queueDelayN1OfStream));
869
870 // Setup scheduled traces; TCP traces must be hooked after socket creation
873 &n0TcpRttOfStream);
876 &n0TcpCwndOfStream);
878 Simulator::Schedule(throughputSamplingInterval,
880 &n0TcpThroughputOfStream,
881 throughputSamplingInterval);
882 // Setup scheduled traces; TCP traces must be hooked after socket creation
883 if (enableN1Tcp)
884 {
887 &n1TcpRttOfStream);
890 &n1TcpCwndOfStream);
892 }
893 Simulator::Schedule(throughputSamplingInterval,
895 &n1TcpThroughputOfStream,
896 throughputSamplingInterval);
897 Simulator::Schedule(marksSamplingInterval,
899 &marksFrequencyOfStream,
900 marksSamplingInterval);
901 Simulator::Schedule(marksSamplingInterval,
903 &dropsFrequencyOfStream,
904 marksSamplingInterval);
905
906 if (enablePcap)
907 {
908 p2p.EnablePcapAll("FqCoDel-L4S-example", false);
909 }
910
913
914 pingOfStream.close();
915 n0TcpCwndOfStream.close();
916 n0TcpRttOfStream.close();
917 n0TcpThroughputOfStream.close();
918 n1TcpCwndOfStream.close();
919 n1TcpRttOfStream.close();
920 n1TcpThroughputOfStream.close();
921 dropOfStream.close();
922 markOfStream.close();
923 dropsFrequencyOfStream.close();
924 marksFrequencyOfStream.close();
925 lengthOfStream.close();
926 queueDelayN0OfStream.close();
927 queueDelayN1OfStream.close();
928
929 return 0;
930}
a polymophic address class
Definition address.h:90
holds a vector of ns3::Application pointers.
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
Ptr< Application > Get(uint32_t i) const
Get the Ptr<Application> stored in this container at a given index.
void Stop(Time stop) const
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
A helper to make it easier to instantiate an ns3::BulkSendApplication on a set of nodes.
static TypeId GetTypeId()
Get the type ID.
Parse command-line arguments.
Class for representing data rates.
Definition data-rate.h:78
uint64_t GetBitRate() const
Get the underlying bitrate.
Definition data-rate.cc:234
static TypeId GetTypeId()
Get the type ID.
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
void InstallAll() const
Aggregate IPv4, IPv6, UDP, and TCP stacks to all nodes in the simulation.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
Ipv4 addresses are stored in host order in this class.
static Ipv4Address GetAny()
static void PopulateRoutingTables()
Build a routing database and initialize the routing tables of the nodes in the simulation.
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
Ipv4QueueDiscItem is a subclass of QueueDiscItem which stores IPv4 packets.
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
Create a ping application and associate it to a node.
Definition ping-helper.h:31
This application behaves similarly to the Unix ping application, although with fewer options supporte...
Definition ping.h:45
Build a set of PointToPointNetDevice objects.
A Device for a Point to Point Network Link.
Smart pointer class similar to boost::intrusive_ptr.
Class for representing queue sizes.
Definition queue-size.h:85
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static void Run()
Run the simulation.
Definition simulator.cc:167
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
Hold variables of type string.
Definition string.h:45
static TypeId GetTypeId()
Get the type ID.
Definition tcp-bic.cc:19
static TypeId GetTypeId()
Get the type ID.
Definition tcp-dctcp.cc:25
TCP socket creation and multiplexing/demultiplexing.
static TypeId GetTypeId()
Get the type ID.
static TypeId GetTypeId()
Get the type ID.
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:392
int64_t GetMicroSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition nstime.h:402
Build a set of QueueDisc objects.
QueueDiscContainer Install(NetDeviceContainer c)
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.
void SetQueueLimits(std::string type, Args &&... args)
Helper function used to add a queue limits object to the transmission queues of the devices.
The Traffic Control layer aims at introducing an equivalent of the Linux Traffic Control infrastructu...
a unique identifier for an interface.
Definition type-id.h:48
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition type-id.cc:872
std::string GetName() const
Get the name.
Definition type-id.cc:1061
Hold an unsigned integer type.
Definition uinteger.h:34
Time stopTime
void TraceDropsFrequency(std::ofstream *ofStream, Time dropsSamplingInterval)
void TraceN0Rx(Ptr< const Packet > packet, const Address &address)
void ScheduleN0TcpCwndTraceConnection(std::ofstream *ofStream)
void TraceMarksFrequency(std::ofstream *ofStream, Time marksSamplingInterval)
void ScheduleN1TcpRttTraceConnection(std::ofstream *ofStream)
void TraceN0Cwnd(std::ofstream *ofStream, uint32_t oldCwnd, uint32_t newCwnd)
void TraceN1Throughput(std::ofstream *ofStream, Time throughputInterval)
void TraceMark(std::ofstream *ofStream, Ptr< const QueueDiscItem > item, const char *reason)
void TraceN1Cwnd(std::ofstream *ofStream, uint32_t oldCwnd, uint32_t newCwnd)
uint32_t g_n1BytesReceived
double avgQueueDiscSize
void TraceDrop(std::ofstream *ofStream, Ptr< const QueueDiscItem > item)
uint32_t g_n0BytesReceived
void TraceN0Throughput(std::ofstream *ofStream, Time throughputInterval)
uint32_t g_marksObserved
void TraceN1Rtt(std::ofstream *ofStream, Time oldRtt, Time newRtt)
void ScheduleN1PacketSinkConnection()
void ScheduleN1TcpCwndTraceConnection(std::ofstream *ofStream)
void ScheduleN0PacketSinkConnection()
void TraceN0Rtt(std::ofstream *ofStream, Time oldRtt, Time newRtt)
uint32_t g_dropsObserved
static void PacketDequeue(std::ofstream *n0OfStream, std::ofstream *n1OfStream, Ptr< const QueueDiscItem > item)
void TraceQueueLength(std::ofstream *ofStream, DataRate linkRate, uint32_t oldVal, uint32_t newVal)
void TraceN1Rx(Ptr< const Packet > packet, const Address &address)
uint32_t checkTimes
void TracePingRtt(std::ofstream *ofStream, uint16_t seqNo, Time rtt)
void ScheduleN0TcpRttTraceConnection(std::ofstream *ofStream)
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:883
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition config.cc:943
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#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
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
Definition callback.h:745
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1332
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
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.
U * PeekPointer(const Ptr< U > &p)
Definition ptr.h:443
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:684
std::string dir