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))
186 else if ((now > 5.795) && (now < 6) && (cwnd > 190))
190 else if ((now > 14) && (now < 14.328) && (cwnd < 225))
194 else if ((now > 17) && (now < 18.2) && (cwnd < 225))
212 if ((now < 7.5) && (
alpha < 0.1))
216 else if ((now > 11) && (now < 30) && (
alpha > 0.01))
220 else if ((now > 34) && (
alpha < 0.015) && (
alpha > 0.025))
228 if ((now > 5.6) && (
alpha > 0.1))
232 if ((now > 7) && ((
alpha > 0.09) || (
alpha < 0.055)))
352 if ((now < 14) && (throughput > 20))
356 if ((now < 30) && (throughput > 48))
360 if ((now > 32) && ((throughput < 47.5) || (throughput > 48.5)))
368 if ((now > 5.6) && ((throughput < 48) || (throughput > 49)))
435 main (
int argc,
char *argv[])
440 uint32_t pingSize = 100;
441 bool enableSecondTcp =
false;
442 bool enableLogging =
false;
446 std::string pingTraceFile =
"tcp-validation-ping.dat";
447 std::string firstTcpRttTraceFile =
"tcp-validation-first-tcp-rtt.dat";
448 std::string firstTcpCwndTraceFile =
"tcp-validation-first-tcp-cwnd.dat";
449 std::string firstDctcpTraceFile =
"tcp-validation-first-dctcp-alpha.dat";
450 std::string firstTcpThroughputTraceFile =
"tcp-validation-first-tcp-throughput.dat";
451 std::string secondTcpRttTraceFile =
"tcp-validation-second-tcp-rtt.dat";
452 std::string secondTcpCwndTraceFile =
"tcp-validation-second-tcp-cwnd.dat";
453 std::string secondTcpThroughputTraceFile =
"tcp-validation-second-tcp-throughput.dat";
454 std::string secondDctcpTraceFile =
"tcp-validation-second-dctcp-alpha.dat";
455 std::string queueMarkTraceFile =
"tcp-validation-queue-mark.dat";
456 std::string queueDropTraceFile =
"tcp-validation-queue-drop.dat";
457 std::string queueMarksFrequencyTraceFile =
"tcp-validation-queue-marks-frequency.dat";
458 std::string queueLengthTraceFile =
"tcp-validation-queue-length.dat";
463 std::string firstTcpType =
"cubic";
464 std::string secondTcpType =
"";
465 std::string queueType =
"codel";
469 bool queueUseEcn =
false;
489 cmd.AddValue (
"firstTcpType",
"first TCP type (cubic, dctcp, or reno)", firstTcpType);
490 cmd.AddValue (
"secondTcpType",
"second TCP type (cubic, dctcp, or reno)", secondTcpType);
491 cmd.AddValue (
"queueType",
"bottleneck queue type (fq, codel, pie, or red)", queueType);
492 cmd.AddValue (
"baseRtt",
"base RTT", baseRtt);
493 cmd.AddValue (
"ceThreshold",
"CoDel CE threshold (for DCTCP)", ceThreshold);
494 cmd.AddValue (
"linkRate",
"data rate of bottleneck link", linkRate);
495 cmd.AddValue (
"stopTime",
"simulation stop time",
stopTime);
496 cmd.AddValue (
"queueUseEcn",
"use ECN on queue", queueUseEcn);
498 cmd.AddValue (
"validate",
"validation case to run",
g_validate);
499 cmd.Parse (argc, argv);
507 ||
g_validate ==
"cubic-50ms-ecn",
"Unknown test");
548 Time oneWayDelay = baseRtt / 2;
551 if (firstTcpType ==
"reno")
555 else if (firstTcpType ==
"cubic")
559 else if (firstTcpType ==
"dctcp")
564 if (queueUseEcn ==
false)
566 std::cout <<
"Warning: using DCTCP with queue ECN disabled" << std::endl;
574 if (secondTcpType ==
"reno")
576 enableSecondTcp =
true;
579 else if (secondTcpType ==
"cubic")
581 enableSecondTcp =
true;
584 else if (secondTcpType ==
"dctcp")
586 enableSecondTcp =
true;
589 else if (secondTcpType ==
"")
591 enableSecondTcp =
false;
599 if (queueType ==
"fq")
603 else if (queueType ==
"codel")
607 else if (queueType ==
"pie")
611 else if (queueType ==
"red")
631 NS_LOG_DEBUG (
"first TCP: " << firstTcpTypeId.
GetName () <<
"; second TCP: " << secondTcpTypeId.
GetName () <<
"; queue: " << queueTypeId.
GetName () <<
"; ceThreshold: " << ceThreshold.
GetSeconds () * 1000 <<
"ms");
634 std::ofstream pingOfStream;
635 std::ofstream firstTcpRttOfStream;
636 std::ofstream firstTcpCwndOfStream;
637 std::ofstream firstTcpThroughputOfStream;
638 std::ofstream firstTcpDctcpOfStream;
639 std::ofstream secondTcpRttOfStream;
640 std::ofstream secondTcpCwndOfStream;
641 std::ofstream secondTcpThroughputOfStream;
642 std::ofstream secondTcpDctcpOfStream;
643 std::ofstream queueDropOfStream;
644 std::ofstream queueMarkOfStream;
645 std::ofstream queueMarksFrequencyOfStream;
646 std::ofstream queueLengthOfStream;
649 pingOfStream.open (pingTraceFile.c_str (), std::ofstream::out);
650 firstTcpRttOfStream.open (firstTcpRttTraceFile.c_str (), std::ofstream::out);
651 firstTcpCwndOfStream.open (firstTcpCwndTraceFile.c_str (), std::ofstream::out);
652 firstTcpThroughputOfStream.open (firstTcpThroughputTraceFile.c_str (), std::ofstream::out);
653 if (firstTcpType ==
"dctcp")
655 firstTcpDctcpOfStream.open (firstDctcpTraceFile.c_str (), std::ofstream::out);
659 secondTcpRttOfStream.open (secondTcpRttTraceFile.c_str (), std::ofstream::out);
660 secondTcpCwndOfStream.open (secondTcpCwndTraceFile.c_str (), std::ofstream::out);
661 secondTcpThroughputOfStream.open (secondTcpThroughputTraceFile.c_str (), std::ofstream::out);
662 if (secondTcpType ==
"dctcp")
664 secondTcpDctcpOfStream.open (secondDctcpTraceFile.c_str (), std::ofstream::out);
667 queueDropOfStream.open (queueDropTraceFile.c_str (), std::ofstream::out);
668 queueMarkOfStream.open (queueMarkTraceFile.c_str (), std::ofstream::out);
669 queueMarksFrequencyOfStream.open (queueMarksFrequencyTraceFile.c_str (), std::ofstream::out);
670 queueLengthOfStream.open (queueLengthTraceFile.c_str (), std::ofstream::out);
676 Ptr<Node> pingServer = CreateObject<Node> ();
677 Ptr<Node> firstServer = CreateObject<Node> ();
678 Ptr<Node> secondServer = CreateObject<Node> ();
679 Ptr<Node> wanRouter = CreateObject<Node> ();
680 Ptr<Node> lanRouter = CreateObject<Node> ();
681 Ptr<Node> pingClient = CreateObject<Node> ();
682 Ptr<Node> firstClient = CreateObject<Node> ();
683 Ptr<Node> secondClient = CreateObject<Node> ();
699 pingServerDevices = p2p.
Install (wanRouter, pingServer);
700 firstServerDevices = p2p.
Install (wanRouter, firstServer);
701 secondServerDevices = p2p.
Install (wanRouter, secondServer);
703 wanLanDevices = p2p.
Install (wanRouter, lanRouter);
706 pingClientDevices = p2p.
Install (lanRouter, pingClient);
707 firstClientDevices = p2p.
Install (lanRouter, firstClient);
708 secondClientDevices = p2p.
Install (lanRouter, secondClient);
715 stackHelper.
Install (pingServer);
717 stackHelper.
Install (firstServer);
719 proto->SetAttribute (
"SocketType",
TypeIdValue (firstTcpTypeId));
720 stackHelper.
Install (secondServer);
721 stackHelper.
Install (wanRouter);
722 stackHelper.
Install (lanRouter);
723 stackHelper.
Install (pingClient);
725 stackHelper.
Install (firstClient);
728 proto->SetAttribute (
"SocketType",
TypeIdValue (firstTcpTypeId));
729 stackHelper.
Install (secondClient);
734 proto->SetAttribute (
"SocketType",
TypeIdValue (secondTcpTypeId));
736 proto->SetAttribute (
"SocketType",
TypeIdValue (secondTcpTypeId));
747 tchFq.
Install (pingServerDevices);
748 tchFq.
Install (firstServerDevices);
749 tchFq.
Install (secondServerDevices);
751 tchFq.
Install (pingClientDevices);
752 tchFq.
Install (firstClientDevices);
753 tchFq.
Install (secondClientDevices);
758 tchBottleneck.
Install (wanLanDevices.
Get (0));
761 ipv4.
SetBase (
"10.1.1.0",
"255.255.255.0");
763 ipv4.
SetBase (
"10.1.2.0",
"255.255.255.0");
765 ipv4.
SetBase (
"10.1.3.0",
"255.255.255.0");
767 ipv4.
SetBase (
"172.16.1.0",
"255.255.255.0");
769 ipv4.
SetBase (
"192.168.1.0",
"255.255.255.0");
771 ipv4.
SetBase (
"192.168.2.0",
"255.255.255.0");
773 ipv4.
SetBase (
"192.168.3.0",
"255.255.255.0");
782 pingHelper.SetAttribute (
"Interval",
TimeValue (pingInterval));
791 uint16_t firstPort = 5000;
797 tcp.SetAttribute (
"Remote",
AddressValue (firstDestAddress));
798 firstApp = tcp.Install (firstServer);
804 PacketSinkHelper firstSinkHelper (
"ns3::TcpSocketFactory", firstSinkAddress);
805 firstSinkApp = firstSinkHelper.Install (firstClient);
813 uint16_t secondPort = 5000;
816 tcp.SetAttribute (
"Remote",
AddressValue (secondDestAddress));
817 secondApp = tcp.Install (secondServer);
822 PacketSinkHelper secondSinkHelper (
"ns3::TcpSocketFactory", secondSinkAddress);
824 secondSinkApp = secondSinkHelper.Install (secondClient);
834 qd = tc->GetRootQueueDiscOnDevice (wanLanDevices.
Get (0));
843 if (firstTcpType ==
"dctcp")
855 if (secondTcpType ==
"dctcp")
873 pingOfStream.close ();
874 firstTcpCwndOfStream.close ();
875 firstTcpRttOfStream.close ();
876 if (firstTcpType ==
"dctcp")
878 firstTcpDctcpOfStream.close ();
880 firstTcpThroughputOfStream.close ();
883 secondTcpCwndOfStream.close ();
884 secondTcpRttOfStream.close ();
885 secondTcpThroughputOfStream.close ();
886 if (secondTcpType ==
"dctcp")
888 secondTcpDctcpOfStream.close ();
891 queueDropOfStream.close ();
892 queueMarkOfStream.close ();
893 queueMarksFrequencyOfStream.close ();
894 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.
static TypeId GetTypeId(void)
Get the type ID.
Parse command-line arguments.
Class for representing data rates.
uint64_t GetBitRate() const
Get the underlying bitrate.
AttributeValue implementation for DataRate.
static TypeId GetTypeId(void)
Get the type ID.
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...
static Ipv4Address GetAny(void)
static void PopulateRoutingTables(void)
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.
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 ...
static TypeId GetTypeId(void)
Get the type ID.
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.
static TypeId GetTypeId(void)
Get the type ID.
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static void Run(void)
Run the simulation.
static Time Now(void)
Return the current simulation virtual time.
Hold variables of type string.
static TypeId GetTypeId(void)
Get the type ID.
static TypeId GetTypeId(void)
Get the type ID.
TCP socket creation and multiplexing/demultiplexing.
static TypeId GetTypeId(void)
Get the type ID.
static TypeId GetTypeId(void)
Get the type ID.
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)
#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.
Callback< R > MakeBoundCallback(R(*fnPtr)(TX), ARG a1)
Make Callbacks with one bound argument.
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.
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...
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...
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)