A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ns3tcp-cubic-test-suite.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010 University of Washington (trace writing)
3 * Copyright (c) 2018-20 NITK Surathkal (topology setup)
4 * Copyright (c) 2024 Tom Henderson (test definition)
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation;
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20// Test suite based on tcp-bbr-example.cc modified topology setup:
21//
22// 1 Gbps 50/100Mbps 1 Gbps
23// Sender -------------- R1 -------------- R2 -------------- Receiver
24// 5us baseRtt/2 5us
25//
26// This is a test suite written initially to test the addition of
27// TCP friendliness but can also be extended for other Cubic tests. By
28// changing some compile-time constants below, it can be used to also produce
29// gnuplots and pcaps that demonstrate the behavior. See the WRITE_PCAP and
30// WRITE_GNUPLOT booleans below to enable this output.
31//
32// There are four cases configured presently.
33// 1. A Cubic TCP on a 5 ms RTT bottleneck, with no fast convergence nor
34// TCP friendliness configured
35// 2. A Cubic TCP on a 5 ms RTT bottleneck, with fast convergence but no
36// TCP friendliness configured. This exhibits a different cwnd plot from 1.
37// 3. A Cubic TCP on a 20 ms RTT bottleneck, with fast convergence but no
38// TCP friendliness configured. There is a step change increase in
39// bottleneck link capacity but the TCP is slow to exploit it.
40// 4. A Cubic TCP on a 20 ms RTT bottleneck, with fast convergence and
41// TCP friendliness configured. There is a step change increase in
42// bottleneck link capacity and the TCP responds more quickly than in 3.
43
44#include "ns3/abort.h"
45#include "ns3/bulk-send-helper.h"
46#include "ns3/config.h"
47#include "ns3/data-rate.h"
48#include "ns3/error-model.h"
49#include "ns3/gnuplot.h"
50#include "ns3/inet-socket-address.h"
51#include "ns3/internet-stack-helper.h"
52#include "ns3/ipv4-address-helper.h"
53#include "ns3/ipv4-global-routing-helper.h"
54#include "ns3/log.h"
55#include "ns3/node-container.h"
56#include "ns3/output-stream-wrapper.h"
57#include "ns3/packet-sink-helper.h"
58#include "ns3/pcap-file.h"
59#include "ns3/point-to-point-helper.h"
60#include "ns3/point-to-point-net-device.h"
61#include "ns3/pointer.h"
62#include "ns3/simulator.h"
63#include "ns3/string.h"
64#include "ns3/tcp-header.h"
65#include "ns3/tcp-socket-factory.h"
66#include "ns3/test.h"
67#include "ns3/trace-helper.h"
68#include "ns3/traffic-control-helper.h"
69#include "ns3/uinteger.h"
70
71#include <iomanip>
72
73using namespace ns3;
74
75NS_LOG_COMPONENT_DEFINE("Ns3TcpCubicTest");
76
77static constexpr bool WRITE_PCAP = false; //!< Set to true to write out pcap.
78static constexpr bool WRITE_GNUPLOT = false; //!< Set to true to write out gnuplot.
79
80/**
81 * \ingroup system-tests-tcp
82 *
83 * Add sample trace values to data structures
84 * \param gnuplotTimeSeries Gnuplot data structure
85 * \param timeSeries time series of cwnd changes
86 * \param oldval old value of cwnd
87 * \param newval new value of cwnd
88 */
89void
91 std::map<Time, double>* timeSeries,
92 uint32_t oldval,
93 uint32_t newval)
94{
95 // We store data in two structures because Gnuplot2DDataset data is not exportable
96 NS_LOG_DEBUG("cwnd " << newval / 1448.0);
97 gnuplotTimeSeries->Add(Simulator::Now().GetSeconds(), newval / 1448.0);
98 timeSeries->insert_or_assign(Simulator::Now(), newval / 1448.0);
99}
100
101/**
102 * \ingroup system-tests-tcp
103 * Test Cubic response
104 */
106{
107 public:
108 /**
109 * Constructor.
110 *
111 * \param testCase testcase name
112 * \param prefix filename prefix if writing output files
113 * \param fastConvergence whether to enable fast convergence
114 * \param tcpFriendliness whether to enable TCP friendliness
115 * \param baseRtt base RTT to use for test case
116 * \param capacityIncrease whether to trigger a sudden capacity increase
117 */
118 Ns3TcpCubicTestCase(std::string testCase,
119 std::string prefix,
120 bool fastConvergence,
121 bool tcpFriendliness,
122 Time baseRtt,
123 bool capacityIncrease);
124 ~Ns3TcpCubicTestCase() override;
125
126 private:
127 void DoRun() override;
128
129 /**
130 * Connect TCP cwnd trace after socket is instantiated
131 *
132 * \param nodeId node ID to connect to
133 * \param socketId socket ID to connect to
134 */
135 void ConnectCwndTrace(uint32_t nodeId, uint32_t socketId);
136
137 /**
138 * Increases the device bandwidth to 100 Mbps
139 * \param device device to modify
140 */
142
143 /**
144 * Check that time series values within a time range are within a value range.
145 * \param start start of time range
146 * \param end end of time range
147 * \param lowerBound lower bound of acceptable values
148 * \param upperBound upper bound of acceptable values
149 * \return true if values are within range
150 */
151 bool CheckValues(Time start, Time end, double lowerBound, double upperBound);
152
153 bool m_writeResults{WRITE_PCAP}; //!< Whether to write pcaps
154 bool m_writeGnuplot{WRITE_GNUPLOT}; //!< Whether to write gnuplot files
155 Gnuplot2dDataset m_cwndTimeSeries; //!< cwnd time series
156 std::map<Time, double> m_timeSeries; //!< time series to check
157 std::string m_prefix; //!< filename prefix if writing files
158 bool m_fastConvergence; //!< whether to enable fast convergence
159 bool m_tcpFriendliness; //!< whether to enable TCP friendliness
160 Time m_baseRtt; //!< the base RTT to use
161 bool m_capacityIncrease; //!< whether to trigger a capacity increase
162};
163
165 std::string prefix,
166 bool fastConvergence,
167 bool tcpFriendliness,
168 Time baseRtt,
169 bool capacityIncrease)
170 : TestCase(testCase),
171 m_prefix(prefix),
172 m_fastConvergence(fastConvergence),
173 m_tcpFriendliness(tcpFriendliness),
174 m_baseRtt(baseRtt),
175 m_capacityIncrease(capacityIncrease)
176{
177}
178
180{
181}
182
183void
185{
186 device->SetDataRate(DataRate("100Mbps"));
187}
188
189void
191{
193 "/NodeList/" + std::to_string(nodeId) + "/$ns3::TcpL4Protocol/SocketList/" +
194 std::to_string(socketId) + "/CongestionWindow",
196}
197
198bool
199Ns3TcpCubicTestCase::CheckValues(Time start, Time end, double lowerBound, double upperBound)
200{
201 auto itStart = m_timeSeries.lower_bound(start);
202 auto itEnd = m_timeSeries.upper_bound(end);
203 for (auto it = itStart; it != itEnd; it++)
204 {
205 if (it->second < lowerBound || it->second > upperBound)
206 {
207 NS_LOG_DEBUG("Value " << it->second << " at time " << it->first.GetSeconds()
208 << " outside range (" << lowerBound << "," << upperBound << ")");
209 return false;
210 }
211 }
212 return true;
213}
214
215void
217{
218 NS_LOG_DEBUG("Running " << m_prefix);
219 // The maximum bandwidth delay product is 20 ms (base RTT) times 100 Mbps
220 // which works out to 250KB. Setting the socket buffer sizes to four times
221 // that value (1MB) should be more than enough.
222 Config::SetDefault("ns3::TcpSocket::SndBufSize", UintegerValue(1000000));
223 Config::SetDefault("ns3::TcpSocket::RcvBufSize", UintegerValue(1000000));
224 Config::SetDefault("ns3::TcpSocket::InitialCwnd", UintegerValue(10));
225 Config::SetDefault("ns3::TcpSocket::DelAckCount", UintegerValue(2));
226 Config::SetDefault("ns3::TcpSocket::SegmentSize", UintegerValue(1448));
227 Config::SetDefault("ns3::TcpSocketState::EnablePacing", BooleanValue(true));
228 Config::SetDefault("ns3::TcpSocketState::PaceInitialWindow", BooleanValue(true));
229 Config::SetDefault("ns3::TcpCubic::FastConvergence", BooleanValue(m_fastConvergence));
230 Config::SetDefault("ns3::TcpCubic::TcpFriendliness", BooleanValue(m_tcpFriendliness));
231
232 Time stopTime = Seconds(20);
233
234 NodeContainer sender;
235 NodeContainer receiver;
236 NodeContainer routers;
237 sender.Create(1);
238 receiver.Create(1);
239 routers.Create(2);
240
241 // Create the point-to-point link helpers
242 PointToPointHelper bottleneckLink;
243 // With the DynamicQueueLimits setting below, the following statement
244 // will minimize the buffering in the device and force most buffering
245 // into the AQM
246 bottleneckLink.SetQueue("ns3::DropTailQueue", "MaxSize", StringValue("2p"));
248 {
249 // Start at a lower capacity, and increase later
250 bottleneckLink.SetDeviceAttribute("DataRate", StringValue("50Mbps"));
251 }
252 else
253 {
254 bottleneckLink.SetDeviceAttribute("DataRate", StringValue("100Mbps"));
255 }
256 bottleneckLink.SetChannelAttribute("Delay", TimeValue(m_baseRtt / 2));
257
258 PointToPointHelper edgeLink;
259 edgeLink.SetDeviceAttribute("DataRate", StringValue("1000Mbps"));
260 edgeLink.SetChannelAttribute("Delay", StringValue("5us"));
261
262 // Create NetDevice containers
263 NetDeviceContainer senderEdge = edgeLink.Install(sender.Get(0), routers.Get(0));
264 NetDeviceContainer r1r2 = bottleneckLink.Install(routers.Get(0), routers.Get(1));
265 NetDeviceContainer receiverEdge = edgeLink.Install(routers.Get(1), receiver.Get(0));
266
267 // Install Stack
268 InternetStackHelper internet;
269 internet.Install(sender);
270 internet.Install(receiver);
271 internet.Install(routers);
272
273 // Configure the root queue discipline
275 tch.SetRootQueueDisc("ns3::FqCoDelQueueDisc");
276 tch.SetQueueLimits("ns3::DynamicQueueLimits");
277
278 tch.Install(senderEdge);
279 tch.Install(receiverEdge);
280
281 // Assign IP addresses
283 ipv4.SetBase("10.0.0.0", "255.255.255.0");
284
285 Ipv4InterfaceContainer i1i2 = ipv4.Assign(r1r2);
286 ipv4.NewNetwork();
287 Ipv4InterfaceContainer is1 = ipv4.Assign(senderEdge);
288 ipv4.NewNetwork();
289 Ipv4InterfaceContainer ir1 = ipv4.Assign(receiverEdge);
290
291 // Populate routing tables
293
294 // Select sender side port
295 uint16_t port = 50001;
296
297 // Install application on the sender
298 BulkSendHelper source("ns3::TcpSocketFactory", InetSocketAddress(ir1.GetAddress(1), port));
299 source.SetAttribute("MaxBytes", UintegerValue(0));
300 ApplicationContainer sourceApps = source.Install(sender.Get(0));
301 sourceApps.Start(Seconds(0.1));
302 // Hook trace source after application starts
305 this,
306 0,
307 0);
308 sourceApps.Stop(stopTime);
309
310 // Install application on the receiver
311 PacketSinkHelper sink("ns3::TcpSocketFactory", InetSocketAddress(Ipv4Address::GetAny(), port));
312 ApplicationContainer sinkApps = sink.Install(receiver.Get(0));
313 sinkApps.Start(Seconds(0.0));
314 sinkApps.Stop(stopTime);
315
317 {
318 // Double the capacity of the bottleneck link at 10 seconds
319 Ptr<PointToPointNetDevice> device = r1r2.Get(0)->GetObject<PointToPointNetDevice>();
321 }
322
323 std::ostringstream oss;
324 oss << m_prefix;
325 if (m_writeResults)
326 {
327 edgeLink.EnablePcap(oss.str(), senderEdge.Get(0));
328 edgeLink.EnablePcap(oss.str(), receiverEdge.Get(0));
329 edgeLink.EnableAscii(oss.str(), senderEdge.Get(0));
330 edgeLink.EnableAscii(oss.str(), receiverEdge.Get(0));
331 }
334
335 if (m_writeGnuplot)
336 {
337 std::ofstream outfile(oss.str() + ".plt");
338
339 std::string capacityIncreaseString;
341 {
342 capacityIncreaseString = " capacity increase = 1";
343 }
344 Gnuplot gnuplot = Gnuplot(
345 oss.str() + ".eps",
346 "Cubic concave/convex response (" + std::to_string(m_baseRtt.GetMilliSeconds()) +
347 " ms RTT, 1448 byte segs, 100 Mbps bottleneck)\\nFast convergence = " +
348 std::to_string(m_fastConvergence) +
349 " friendliness = " + std::to_string(m_tcpFriendliness) + capacityIncreaseString);
350 gnuplot.SetTerminal("post eps color enhanced");
351 gnuplot.SetLegend("Time (seconds)", "Cwnd (segments)");
354 gnuplot.GenerateOutput(outfile);
355 }
356
357 // Check that cwnd values are within tolerance of expected values
358 // The expected values were determined by inspecting the plots generated
359 if (m_prefix == "ns3-tcp-cubic-no-heuristic")
360 {
361 // Check overall min and max
363 true,
364 "cwnd outside range");
365 // Time just before a reduction does not have much variation
367 true,
368 "cwnd outside range");
369 }
370 else if (m_prefix == "ns3-tcp-cubic-fast-conv")
371 {
372 // Check overall min and max
374 true,
375 "cwnd outside range");
376 // Initial convex region does not have much variation
378 true,
379 "cwnd outside range");
380 }
381 else if (m_prefix == "ns3-tcp-cubic-no-friendly")
382 {
383 // Between time 12 and 16, cwnd should be fairly constant
384 // because without TCP friendliness, Cubic does not respond quickly
386 true,
387 "cwnd outside range");
388 // After time 19.5, cwnd should have grown much higher
389 NS_TEST_ASSERT_MSG_EQ(CheckValues(Seconds(19.5), Seconds(20), 180, 210),
390 true,
391 "cwnd outside range");
392 }
393 else if (m_prefix == "ns3-tcp-cubic-friendly")
394 {
395 // In contrast to previous case, cwnd should grow above 150 much sooner
397 true,
398 "cwnd outside range");
399 }
400
402}
403
404/**
405 * \ingroup system-tests-tcp
406 * TestSuite for module tcp-cubic
407 */
409{
410 public:
412};
413
415 : TestSuite("ns3-tcp-cubic", Type::UNIT)
416{
417 // Test Cubic with no fast convergence or TCP friendliness enabled
418 // This results in a cwnd plot that has only the concave portion of
419 // returning cwnd to Wmax
420 AddTestCase(new Ns3TcpCubicTestCase("no heuristic",
421 "ns3-tcp-cubic-no-heuristic",
422 false,
423 false,
424 MilliSeconds(5),
425 false),
426 TestCase::Duration::QUICK);
427
428 // Test Cubic with fast convergence but no TCP friendliness enabled
429 // This results in a cwnd plot that has concave and convex regions, as
430 // well as convex-only regions; also observed on Linux testbeds
431 AddTestCase(new Ns3TcpCubicTestCase("fast convergence on",
432 "ns3-tcp-cubic-fast-conv",
433 true,
434 false,
435 MilliSeconds(5),
436 false),
437 TestCase::Duration::QUICK);
438
439 // Test Cubic with fast convergence but no TCP friendliness enabled
440 // with a higher RTT (20ms) and a step change in capacity at time 10s.
441 // This results in a sluggish response by TCP Cubic to use the new capacity.
442 AddTestCase(new Ns3TcpCubicTestCase("fast convergence on, Reno friendliness off",
443 "ns3-tcp-cubic-no-friendly",
444 true,
445 false,
446 MilliSeconds(20),
447 true),
448 TestCase::Duration::QUICK);
449
450 // Test Cubic with fast convergence but with TCP friendliness enabled
451 // with a higher RTT (20ms) and a step change in capacity at time 10s.
452 // This results in a faster response by TCP Cubic to use the new capacity.
453 AddTestCase(new Ns3TcpCubicTestCase("fast convergence on, Reno friendliness on",
454 "ns3-tcp-cubic-friendly",
455 true,
456 true,
457 MilliSeconds(20),
458 true),
459 TestCase::Duration::QUICK);
460}
461
462/**
463 * Static variable for test initialization
464 */
Ipv4InterfaceContainer i1i2
IPv4 interface container i1 + i2.
Gnuplot2dDataset m_cwndTimeSeries
cwnd time series
bool m_tcpFriendliness
whether to enable TCP friendliness
void DoRun() override
Implementation to actually run this TestCase.
Time m_baseRtt
the base RTT to use
void ConnectCwndTrace(uint32_t nodeId, uint32_t socketId)
Connect TCP cwnd trace after socket is instantiated.
std::string m_prefix
filename prefix if writing files
Ns3TcpCubicTestCase(std::string testCase, std::string prefix, bool fastConvergence, bool tcpFriendliness, Time baseRtt, bool capacityIncrease)
Constructor.
bool m_writeGnuplot
Whether to write gnuplot files.
bool m_capacityIncrease
whether to trigger a capacity increase
bool m_fastConvergence
whether to enable fast convergence
bool m_writeResults
Whether to write pcaps.
std::map< Time, double > m_timeSeries
time series to check
void IncreaseBandwidth(Ptr< PointToPointNetDevice > device)
Increases the device bandwidth to 100 Mbps.
bool CheckValues(Time start, Time end, double lowerBound, double upperBound)
Check that time series values within a time range are within a value range.
TestSuite for module tcp-cubic.
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.
void Stop(Time stop) const
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
ApplicationContainer Install(NodeContainer c)
Install an application on each node of the input container configured with all the attributes set wit...
void SetAttribute(const std::string &name, const AttributeValue &value)
Helper function used to set the underlying application attributes.
void EnableAscii(std::string prefix, Ptr< NetDevice > nd, bool explicitFilename=false)
Enable ascii trace output on the indicated net device.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
A helper to make it easier to instantiate an ns3::BulkSendApplication on a set of nodes.
Class for representing data rates.
Definition: data-rate.h:89
Class to represent a 2D points plot.
Definition: gnuplot.h:116
void Add(double x, double y)
Definition: gnuplot.cc:377
void SetTitle(const std::string &title)
Change line title.
Definition: gnuplot.cc:148
a simple class to generate gnuplot-ready plotting commands from a set of datasets.
Definition: gnuplot.h:370
void AddDataset(const GnuplotDataset &dataset)
Definition: gnuplot.cc:796
void SetLegend(const std::string &xLegend, const std::string &yLegend)
Definition: gnuplot.cc:776
void SetTerminal(const std::string &terminal)
Definition: gnuplot.cc:764
void GenerateOutput(std::ostream &os)
Writes gnuplot commands and data values to a single output stream.
Definition: gnuplot.cc:802
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
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
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.
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
void EnablePcap(std::string prefix, Ptr< NetDevice > nd, bool promiscuous=false, bool explicitFilename=false)
Enable pcap output the indicated net device.
Build a set of PointToPointNetDevice objects.
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
void SetQueue(std::string type, Ts &&... args)
Each point to point net device must have a queue to pass packets through.
NetDeviceContainer Install(NodeContainer c)
A Device for a Point to Point Network Link.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static void Run()
Run the simulation.
Definition: simulator.cc:178
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
Hold variables of type string.
Definition: string.h:56
encapsulates test code
Definition: test.h:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
int64_t GetMilliSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:408
AttributeValue implementation for Time.
Definition: nstime.h:1406
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.
Hold an unsigned integer type.
Definition: uinteger.h:45
uint16_t port
Definition: dsdv-manet.cc:44
Time stopTime
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:894
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:954
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
Definition: callback.h:767
void CubicCwndTracer(Gnuplot2dDataset *gnuplotTimeSeries, std::map< Time, double > *timeSeries, uint32_t oldval, uint32_t newval)
Add sample trace values to data structures.
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:145
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1331
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static constexpr bool WRITE_PCAP
Set to true to write out pcap.
static Ns3TcpCubicTestSuite ns3TcpCubicTestSuite
Static variable for test initialization.
static constexpr bool WRITE_GNUPLOT
Set to true to write out gnuplot.
Ptr< PacketSink > sink
Pointer to the packet sink application.
Definition: wifi-tcp.cc:55