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"
181 double cwnd =
static_cast<double> (newCwnd) / 1448;
182 if ((now > 5.43) && (now < 5.465) && (cwnd < 500))
184 NS_LOG_WARN (
"now " <<
Now ().As (Time::S) <<
" cwnd " << cwnd <<
" (expected >= 500)");
187 else if ((now > 5.795) && (now < 6) && (cwnd > 190))
189 NS_LOG_WARN (
"now " <<
Now ().As (Time::S) <<
" cwnd " << cwnd <<
" (expected <= 190)");
192 else if ((now > 14) && (now < 14.197) && (cwnd < 224))
194 NS_LOG_WARN (
"now " <<
Now ().As (Time::S) <<
" cwnd " << cwnd <<
" (expected >= 224)");
197 else if ((now > 17) && (now < 18.026) && (cwnd < 212))
199 NS_LOG_WARN (
"now " <<
Now ().As (Time::S) <<
" cwnd " << cwnd <<
" (expected >= 212)");
216 if ((now < 7.5) && (
alpha < 0.1))
221 else if ((now > 11) && (now < 30) && (
alpha > 0.01))
223 NS_LOG_WARN (
"now " <<
Now ().As (Time::S) <<
" alpha " <<
alpha <<
" (expected <= 0.01)");
226 else if ((now > 34) && (
alpha < 0.015) && (
alpha > 0.025))
228 NS_LOG_WARN (
"now " <<
Now ().As (Time::S) <<
" alpha " <<
alpha <<
" (expected 0.015 <= alpha <= 0.025)");
235 if ((now > 5.6) && (
alpha > 0.1))
240 if ((now > 7) && ((
alpha > 0.09) || (
alpha < 0.055)))
242 NS_LOG_WARN (
"now " <<
Now ().As (Time::S) <<
" alpha " <<
alpha <<
" (expected 0.09 <= alpha <= 0.055)");
345 Simulator::Schedule (marksSamplingInterval, &
TraceMarksFrequency, ofStream, marksSamplingInterval);
361 if ((now < 14) && (throughput > 20))
363 NS_LOG_WARN (
"now " <<
Now ().As (Time::S) <<
" throughput " << throughput <<
" (expected <= 20)");
366 if ((now < 30) && (throughput > 48))
368 NS_LOG_WARN (
"now " <<
Now ().As (Time::S) <<
" throughput " << throughput <<
" (expected <= 48)");
371 if ((now > 32) && ((throughput < 47.5) || (throughput > 48.5)))
373 NS_LOG_WARN (
"now " <<
Now ().As (Time::S) <<
" throughput " << throughput <<
" (expected 47.5 <= throughput <= 48.5)");
380 if ((now > 5.6) && ((throughput < 48) || (throughput > 49)))
382 NS_LOG_WARN (
"now " <<
Now ().As (Time::S) <<
" throughput " << throughput <<
" (expected 48 <= throughput <= 49)");
448main (
int argc,
char *argv[])
454 bool enableSecondTcp =
false;
455 bool enableLogging =
false;
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";
476 std::string firstTcpType =
"cubic";
477 std::string secondTcpType =
"";
478 std::string queueType =
"codel";
482 bool queueUseEcn =
false;
484 bool enablePcap =
false;
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);
520 ||
g_validate ==
"cubic-50ms-ecn",
"Unknown test");
561 Time oneWayDelay = baseRtt / 2;
564 if (firstTcpType ==
"reno")
566 firstTcpTypeId = TcpLinuxReno::GetTypeId ();
568 else if (firstTcpType ==
"cubic")
570 firstTcpTypeId = TcpCubic::GetTypeId ();
572 else if (firstTcpType ==
"dctcp")
574 firstTcpTypeId = TcpDctcp::GetTypeId ();
577 if (queueUseEcn ==
false)
579 std::cout <<
"Warning: using DCTCP with queue ECN disabled" << std::endl;
587 if (secondTcpType ==
"reno")
589 enableSecondTcp =
true;
590 secondTcpTypeId = TcpLinuxReno::GetTypeId ();
592 else if (secondTcpType ==
"cubic")
594 enableSecondTcp =
true;
595 secondTcpTypeId = TcpCubic::GetTypeId ();
597 else if (secondTcpType ==
"dctcp")
599 enableSecondTcp =
true;
600 secondTcpTypeId = TcpDctcp::GetTypeId ();
602 else if (secondTcpType ==
"")
604 enableSecondTcp =
false;
612 if (queueType ==
"fq")
614 queueTypeId = FqCoDelQueueDisc::GetTypeId ();
616 else if (queueType ==
"codel")
618 queueTypeId = CoDelQueueDisc::GetTypeId ();
620 else if (queueType ==
"pie")
622 queueTypeId = PieQueueDisc::GetTypeId ();
624 else if (queueType ==
"red")
626 queueTypeId = RedQueueDisc::GetTypeId ();
646 NS_LOG_DEBUG (
"first TCP: " << firstTcpTypeId.
GetName () <<
"; second TCP: " << secondTcpTypeId.
GetName () <<
"; queue: " << queueTypeId.
GetName () <<
"; ceThreshold: " << ceThreshold.
GetSeconds () * 1000 <<
"ms");
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;
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")
675 firstTcpDctcpOfStream.open (firstDctcpTraceFile.c_str (), std::ofstream::out);
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")
684 secondTcpDctcpOfStream.open (secondDctcpTraceFile.c_str (), std::ofstream::out);
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);
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> ();
719 pingServerDevices = p2p.
Install (wanRouter, pingServer);
720 firstServerDevices = p2p.
Install (wanRouter, firstServer);
721 secondServerDevices = p2p.
Install (wanRouter, secondServer);
723 wanLanDevices = p2p.
Install (wanRouter, lanRouter);
726 pingClientDevices = p2p.
Install (lanRouter, pingClient);
727 firstClientDevices = p2p.
Install (lanRouter, firstClient);
728 secondClientDevices = p2p.
Install (lanRouter, secondClient);
735 stackHelper.
Install (pingServer);
737 stackHelper.
Install (firstServer);
739 proto->SetAttribute (
"SocketType",
TypeIdValue (firstTcpTypeId));
740 stackHelper.
Install (secondServer);
741 stackHelper.
Install (wanRouter);
742 stackHelper.
Install (lanRouter);
743 stackHelper.
Install (pingClient);
745 stackHelper.
Install (firstClient);
748 proto->SetAttribute (
"SocketType",
TypeIdValue (firstTcpTypeId));
749 stackHelper.
Install (secondClient);
754 proto->SetAttribute (
"SocketType",
TypeIdValue (secondTcpTypeId));
756 proto->SetAttribute (
"SocketType",
TypeIdValue (secondTcpTypeId));
767 tchFq.
Install (pingServerDevices);
768 tchFq.
Install (firstServerDevices);
769 tchFq.
Install (secondServerDevices);
771 tchFq.
Install (pingClientDevices);
772 tchFq.
Install (firstClientDevices);
773 tchFq.
Install (secondClientDevices);
778 tchBottleneck.
Install (wanLanDevices.
Get (0));
781 ipv4.
SetBase (
"10.1.1.0",
"255.255.255.0");
783 ipv4.
SetBase (
"10.1.2.0",
"255.255.255.0");
785 ipv4.
SetBase (
"10.1.3.0",
"255.255.255.0");
787 ipv4.
SetBase (
"172.16.1.0",
"255.255.255.0");
789 ipv4.
SetBase (
"192.168.1.0",
"255.255.255.0");
791 ipv4.
SetBase (
"192.168.2.0",
"255.255.255.0");
793 ipv4.
SetBase (
"192.168.3.0",
"255.255.255.0");
796 Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
802 pingHelper.SetAttribute (
"Interval",
TimeValue (pingInterval));
811 uint16_t firstPort = 5000;
817 tcp.SetAttribute (
"Remote",
AddressValue (firstDestAddress));
818 firstApp = tcp.Install (firstServer);
824 PacketSinkHelper firstSinkHelper (
"ns3::TcpSocketFactory", firstSinkAddress);
825 firstSinkApp = firstSinkHelper.Install (firstClient);
833 uint16_t secondPort = 5000;
836 tcp.SetAttribute (
"Remote",
AddressValue (secondDestAddress));
837 secondApp = tcp.Install (secondServer);
842 PacketSinkHelper secondSinkHelper (
"ns3::TcpSocketFactory", secondSinkAddress);
844 secondSinkApp = secondSinkHelper.Install (secondClient);
854 qd = tc->GetRootQueueDiscOnDevice (wanLanDevices.
Get (0));
863 if (firstTcpType ==
"dctcp")
867 Simulator::Schedule (throughputSamplingInterval, &
TraceFirstThroughput, &firstTcpThroughputOfStream, throughputSamplingInterval);
874 Simulator::Schedule (throughputSamplingInterval, &
TraceSecondThroughput, &secondTcpThroughputOfStream, throughputSamplingInterval);
875 if (secondTcpType ==
"dctcp")
880 Simulator::Schedule (marksSamplingInterval, &
TraceMarksFrequency, &queueMarksFrequencyOfStream, marksSamplingInterval);
889 Simulator::Destroy ();
893 pingOfStream.close ();
894 firstTcpCwndOfStream.close ();
895 firstTcpRttOfStream.close ();
896 if (firstTcpType ==
"dctcp")
898 firstTcpDctcpOfStream.close ();
900 firstTcpThroughputOfStream.close ();
903 secondTcpCwndOfStream.close ();
904 secondTcpRttOfStream.close ();
905 secondTcpThroughputOfStream.close ();
906 if (secondTcpType ==
"dctcp")
908 secondTcpDctcpOfStream.close ();
911 queueDropOfStream.close ();
912 queueMarkOfStream.close ();
913 queueMarksFrequencyOfStream.close ();
914 queueLengthOfStream.close ();
a polymophic address class
AttributeValue implementation for Address.
holds a vector of ns3::Application pointers.
Ptr< Application > Get(uint32_t i) const
Get the Ptr<Application> stored in this container at a given index.
void Start(Time start)
Arrange for all of the Applications in this container to Start() at the Time given as a parameter.
void Stop(Time stop)
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
AttributeValue implementation for Boolean.
A helper to make it easier to instantiate an ns3::BulkSendApplication on a set of nodes.
Parse command-line arguments.
Class for representing data rates.
uint64_t GetBitRate() const
Get the underlying bitrate.
AttributeValue implementation for DataRate.
aggregate IP/TCP/UDP functionality to existing Nodes.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
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.
virtual Ptr< Node > GetNode(void) const =0
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
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 ...
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 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.
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
NetDeviceContainer Install(NodeContainer c)
A Device for a Point to Point Network Link.
Class for representing queue sizes.
AttributeValue implementation for QueueSize.
Hold variables of type string.
TCP socket creation and multiplexing/demultiplexing.
Simulation virtual time values and global simulation resolution.
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
AttributeValue implementation for Time.
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.
Introspection did not find any typical Config paths.
a unique identifier for an interface.
std::string GetName(void) const
Get the name.
AttributeValue implementation for TypeId.
Hold an unsigned integer type.
Create a IPv4 ping application and associate it to a node.
an application which sends one ICMP ECHO request, waits for a REPLYs and reports the calculated RTT.
void SetDefault(std::string name, const AttributeValue &value)
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
bool ConnectWithoutContextFailSafe(std::string path, const CallbackBase &cb)
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
#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.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Callback< R > MakeBoundCallback(R(*fnPtr)(TX), ARG a1)
Make Callbacks with one bound argument.
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Time Seconds(double value)
Construct a Time in the indicated unit.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
LogLevel
Logging severity classes and levels.
@ LOG_LEVEL_ALL
Print everything.
@ LOG_PREFIX_FUNC
Prefix all trace prints with function.
@ LOG_PREFIX_TIME
Prefix all trace prints with simulation time.
@ LOG_PREFIX_NODE
Prefix all trace prints with simulation node.
void LogComponentEnable(char const *name, enum LogLevel level)
Enable the logging output associated with that log component.
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...
float alpha
Plot alpha value (transparency)
void ScheduleSecondDctcpTraceConnection(std::ofstream *ofStream)
void TraceMarksFrequency(std::ofstream *ofStream, Time marksSamplingInterval)
void ScheduleFirstPacketSinkConnection(void)
void ScheduleSecondTcpRttTraceConnection(std::ofstream *ofStream)
void TraceSecondRtt(std::ofstream *ofStream, Time oldRtt, Time newRtt)
void TraceSecondDctcp(std::ofstream *ofStream, uint32_t bytesMarked, uint32_t bytesAcked, double alpha)
void TraceSecondThroughput(std::ofstream *ofStream, Time throughputInterval)
void TraceFirstThroughput(std::ofstream *ofStream, Time throughputInterval)
void ScheduleFirstDctcpTraceConnection(std::ofstream *ofStream)
void TraceSecondCwnd(std::ofstream *ofStream, uint32_t oldCwnd, uint32_t newCwnd)
void TraceQueueMark(std::ofstream *ofStream, Ptr< const QueueDiscItem > item, const char *reason)
void TraceQueueLength(std::ofstream *ofStream, DataRate queueLinkRate, uint32_t oldVal, uint32_t newVal)
void TracePingRtt(std::ofstream *ofStream, Time rtt)
void TraceFirstRx(Ptr< const Packet > packet, const Address &address)
void TraceFirstCwnd(std::ofstream *ofStream, uint32_t oldCwnd, uint32_t newCwnd)
void TraceQueueDrop(std::ofstream *ofStream, Ptr< const QueueDiscItem > item)
void ScheduleSecondPacketSinkConnection(void)
void ScheduleSecondTcpCwndTraceConnection(std::ofstream *ofStream)
void TraceSecondRx(Ptr< const Packet > packet, const Address &address)
void TraceFirstRtt(std::ofstream *ofStream, Time oldRtt, Time newRtt)
uint32_t g_firstBytesReceived
uint32_t g_secondBytesReceived
void TraceFirstDctcp(std::ofstream *ofStream, uint32_t bytesMarked, uint32_t bytesAcked, double alpha)
void ScheduleFirstTcpRttTraceConnection(std::ofstream *ofStream)
void ScheduleFirstTcpCwndTraceConnection(std::ofstream *ofStream)