147 #include "ns3/applications-module.h"
148 #include "ns3/core-module.h"
149 #include "ns3/internet-apps-module.h"
150 #include "ns3/internet-module.h"
151 #include "ns3/network-module.h"
152 #include "ns3/point-to-point-module.h"
153 #include "ns3/traffic-control-module.h"
193 double cwnd =
static_cast<double>(newCwnd) / 1448;
194 if ((now > 5.43) && (now < 5.465) && (cwnd < 500))
199 else if ((now > 5.795) && (now < 6) && (cwnd > 190))
204 else if ((now > 14) && (now < 14.197) && (cwnd < 224))
209 else if ((now > 17) && (now < 18.026) && (cwnd < 212))
226 TraceFirstDctcp(std::ofstream* ofStream, uint32_t bytesMarked, uint32_t bytesAcked,
double alpha)
236 if ((now < 7.5) && (alpha < 0.1))
241 else if ((now > 11) && (now < 30) && (alpha > 0.01))
246 else if ((now > 34) && (alpha < 0.015) && (alpha > 0.025))
249 <<
" (expected 0.015 <= alpha <= 0.025)");
256 if ((now > 5.6) && (alpha > 0.1))
261 if ((now > 7) && ((alpha > 0.09) || (alpha < 0.055)))
264 <<
" (expected 0.09 <= alpha <= 0.055)");
332 TraceSecondDctcp(std::ofstream* ofStream, uint32_t bytesMarked, uint32_t bytesAcked,
double alpha)
427 <<
static_cast<double>(newVal * 8) / (queueLinkRate.
GetBitRate() / 1000)
449 marksSamplingInterval);
474 <<
" (expected <= 20)");
480 <<
" (expected <= 48)");
486 <<
" (expected 47.5 <= throughput <= 48.5)");
496 <<
" (expected 48 <= throughput <= 49)");
529 "/NodeList/1/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow",
554 "CongestionOps/$ns3::TcpDctcp/CongestionEstimate",
567 "CongestionOps/$ns3::TcpDctcp/CongestionEstimate",
616 main(
int argc,
char* argv[])
621 uint32_t pingSize = 100;
622 bool enableSecondTcp =
false;
623 bool enableLogging =
false;
627 std::string pingTraceFile =
"tcp-validation-ping.dat";
628 std::string firstTcpRttTraceFile =
"tcp-validation-first-tcp-rtt.dat";
629 std::string firstTcpCwndTraceFile =
"tcp-validation-first-tcp-cwnd.dat";
630 std::string firstDctcpTraceFile =
"tcp-validation-first-dctcp-alpha.dat";
631 std::string firstTcpThroughputTraceFile =
"tcp-validation-first-tcp-throughput.dat";
632 std::string secondTcpRttTraceFile =
"tcp-validation-second-tcp-rtt.dat";
633 std::string secondTcpCwndTraceFile =
"tcp-validation-second-tcp-cwnd.dat";
634 std::string secondTcpThroughputTraceFile =
"tcp-validation-second-tcp-throughput.dat";
635 std::string secondDctcpTraceFile =
"tcp-validation-second-dctcp-alpha.dat";
636 std::string queueMarkTraceFile =
"tcp-validation-queue-mark.dat";
637 std::string queueDropTraceFile =
"tcp-validation-queue-drop.dat";
638 std::string queueMarksFrequencyTraceFile =
"tcp-validation-queue-marks-frequency.dat";
639 std::string queueLengthTraceFile =
"tcp-validation-queue-length.dat";
644 std::string firstTcpType =
"cubic";
645 std::string secondTcpType =
"";
646 std::string queueType =
"codel";
650 bool queueUseEcn =
false;
652 bool enablePcap =
false;
674 cmd.AddValue(
"firstTcpType",
"first TCP type (cubic, dctcp, or reno)", firstTcpType);
675 cmd.AddValue(
"secondTcpType",
"second TCP type (cubic, dctcp, or reno)", secondTcpType);
676 cmd.AddValue(
"queueType",
"bottleneck queue type (fq, codel, pie, or red)", queueType);
677 cmd.AddValue(
"baseRtt",
"base RTT", baseRtt);
678 cmd.AddValue(
"ceThreshold",
"CoDel CE threshold (for DCTCP)", ceThreshold);
679 cmd.AddValue(
"linkRate",
"data rate of bottleneck link", linkRate);
680 cmd.AddValue(
"stopTime",
"simulation stop time",
stopTime);
681 cmd.AddValue(
"queueUseEcn",
"use ECN on queue", queueUseEcn);
682 cmd.AddValue(
"enablePcap",
"enable Pcap", enablePcap);
683 cmd.AddValue(
"validate",
"validation case to run",
g_validate);
684 cmd.Parse(argc, argv);
736 Time oneWayDelay = baseRtt / 2;
739 if (firstTcpType ==
"reno")
743 else if (firstTcpType ==
"cubic")
747 else if (firstTcpType ==
"dctcp")
754 std::cout <<
"Warning: using DCTCP with queue ECN disabled" << std::endl;
762 if (secondTcpType ==
"reno")
764 enableSecondTcp =
true;
767 else if (secondTcpType ==
"cubic")
769 enableSecondTcp =
true;
772 else if (secondTcpType ==
"dctcp")
774 enableSecondTcp =
true;
777 else if (secondTcpType.empty())
779 enableSecondTcp =
false;
787 if (queueType ==
"fq")
791 else if (queueType ==
"codel")
795 else if (queueType ==
"pie")
799 else if (queueType ==
"red")
822 <<
"; second TCP: " << secondTcpTypeId.
GetName()
823 <<
"; queue: " << queueTypeId.
GetName()
824 <<
"; ceThreshold: " << ceThreshold.
GetSeconds() * 1000 <<
"ms");
829 <<
"; queue: " << queueTypeId.
GetName()
830 <<
"; ceThreshold: " << ceThreshold.
GetSeconds() * 1000 <<
"ms");
834 std::ofstream pingOfStream;
835 std::ofstream firstTcpRttOfStream;
836 std::ofstream firstTcpCwndOfStream;
837 std::ofstream firstTcpThroughputOfStream;
838 std::ofstream firstTcpDctcpOfStream;
839 std::ofstream secondTcpRttOfStream;
840 std::ofstream secondTcpCwndOfStream;
841 std::ofstream secondTcpThroughputOfStream;
842 std::ofstream secondTcpDctcpOfStream;
843 std::ofstream queueDropOfStream;
844 std::ofstream queueMarkOfStream;
845 std::ofstream queueMarksFrequencyOfStream;
846 std::ofstream queueLengthOfStream;
849 pingOfStream.open(pingTraceFile, std::ofstream::out);
850 firstTcpRttOfStream.open(firstTcpRttTraceFile, std::ofstream::out);
851 firstTcpCwndOfStream.open(firstTcpCwndTraceFile, std::ofstream::out);
852 firstTcpThroughputOfStream.open(firstTcpThroughputTraceFile, std::ofstream::out);
853 if (firstTcpType ==
"dctcp")
855 firstTcpDctcpOfStream.open(firstDctcpTraceFile, std::ofstream::out);
859 secondTcpRttOfStream.open(secondTcpRttTraceFile, std::ofstream::out);
860 secondTcpCwndOfStream.open(secondTcpCwndTraceFile, std::ofstream::out);
861 secondTcpThroughputOfStream.open(secondTcpThroughputTraceFile, std::ofstream::out);
862 if (secondTcpType ==
"dctcp")
864 secondTcpDctcpOfStream.open(secondDctcpTraceFile, std::ofstream::out);
867 queueDropOfStream.open(queueDropTraceFile, std::ofstream::out);
868 queueMarkOfStream.open(queueMarkTraceFile, std::ofstream::out);
869 queueMarksFrequencyOfStream.open(queueMarksFrequencyTraceFile, std::ofstream::out);
870 queueLengthOfStream.open(queueLengthTraceFile, std::ofstream::out);
876 Ptr<Node> pingServer = CreateObject<Node>();
877 Ptr<Node> firstServer = CreateObject<Node>();
878 Ptr<Node> secondServer = CreateObject<Node>();
879 Ptr<Node> wanRouter = CreateObject<Node>();
880 Ptr<Node> lanRouter = CreateObject<Node>();
881 Ptr<Node> pingClient = CreateObject<Node>();
882 Ptr<Node> firstClient = CreateObject<Node>();
883 Ptr<Node> secondClient = CreateObject<Node>();
895 p2p.SetQueue(
"ns3::DropTailQueue",
"MaxSize", QueueSizeValue(
QueueSize(
"3p")));
896 p2p.SetDeviceAttribute(
"DataRate", DataRateValue(
DataRate(
"1000Mbps")));
899 pingServerDevices =
p2p.Install(wanRouter, pingServer);
900 firstServerDevices =
p2p.Install(wanRouter, firstServer);
901 secondServerDevices =
p2p.Install(wanRouter, secondServer);
902 p2p.SetChannelAttribute(
"Delay",
TimeValue(oneWayDelay));
903 wanLanDevices =
p2p.Install(wanRouter, lanRouter);
904 p2p.SetQueue(
"ns3::DropTailQueue",
"MaxSize", QueueSizeValue(
QueueSize(
"3p")));
906 pingClientDevices =
p2p.Install(lanRouter, pingClient);
907 firstClientDevices =
p2p.Install(lanRouter, firstClient);
908 secondClientDevices =
p2p.Install(lanRouter, secondClient);
912 p->SetAttribute(
"DataRate", DataRateValue(linkRate));
915 stackHelper.
Install(pingServer);
917 stackHelper.
Install(firstServer);
919 proto->SetAttribute(
"SocketType",
TypeIdValue(firstTcpTypeId));
920 stackHelper.
Install(secondServer);
921 stackHelper.
Install(wanRouter);
922 stackHelper.
Install(lanRouter);
923 stackHelper.
Install(pingClient);
925 stackHelper.
Install(firstClient);
928 proto->SetAttribute(
"SocketType",
TypeIdValue(firstTcpTypeId));
929 stackHelper.
Install(secondClient);
934 proto->SetAttribute(
"SocketType",
TypeIdValue(secondTcpTypeId));
936 proto->SetAttribute(
"SocketType",
TypeIdValue(secondTcpTypeId));
947 tchFq.
Install(pingServerDevices);
948 tchFq.
Install(firstServerDevices);
949 tchFq.
Install(secondServerDevices);
951 tchFq.
Install(pingClientDevices);
952 tchFq.
Install(firstClientDevices);
953 tchFq.
Install(secondClientDevices);
961 ipv4.SetBase(
"10.1.1.0",
"255.255.255.0");
963 ipv4.SetBase(
"10.1.2.0",
"255.255.255.0");
965 ipv4.SetBase(
"10.1.3.0",
"255.255.255.0");
967 ipv4.SetBase(
"172.16.1.0",
"255.255.255.0");
969 ipv4.SetBase(
"192.168.1.0",
"255.255.255.0");
971 ipv4.SetBase(
"192.168.2.0",
"255.255.255.0");
973 ipv4.SetBase(
"192.168.3.0",
"255.255.255.0");
982 pingHelper.SetAttribute(
"Interval",
TimeValue(pingInterval));
984 pingHelper.SetAttribute(
"VerboseMode",
EnumValue(Ping::VerboseMode::SILENT));
992 uint16_t firstPort = 5000;
998 tcp.SetAttribute(
"Remote", AddressValue(firstDestAddress));
999 firstApp = tcp.Install(firstServer);
1005 PacketSinkHelper firstSinkHelper(
"ns3::TcpSocketFactory", firstSinkAddress);
1006 firstSinkApp = firstSinkHelper.Install(firstClient);
1011 if (enableSecondTcp)
1014 uint16_t secondPort = 5000;
1017 tcp.SetAttribute(
"Remote", AddressValue(secondDestAddress));
1018 secondApp = tcp.Install(secondServer);
1023 PacketSinkHelper secondSinkHelper(
"ns3::TcpSocketFactory", secondSinkAddress);
1025 secondSinkApp = secondSinkHelper.Install(secondClient);
1035 qd = tc->GetRootQueueDiscOnDevice(wanLanDevices.
Get(0));
1045 &firstTcpRttOfStream);
1048 &firstTcpCwndOfStream);
1050 if (firstTcpType ==
"dctcp")
1054 &firstTcpDctcpOfStream);
1058 &firstTcpThroughputOfStream,
1059 throughputSamplingInterval);
1060 if (enableSecondTcp)
1065 &secondTcpRttOfStream);
1068 &secondTcpCwndOfStream);
1072 &secondTcpThroughputOfStream,
1073 throughputSamplingInterval);
1074 if (secondTcpType ==
"dctcp")
1078 &secondTcpDctcpOfStream);
1083 &queueMarksFrequencyOfStream,
1084 marksSamplingInterval);
1088 p2p.EnablePcapAll(
"tcp-validation",
false);
1097 pingOfStream.close();
1098 firstTcpCwndOfStream.close();
1099 firstTcpRttOfStream.close();
1100 if (firstTcpType ==
"dctcp")
1102 firstTcpDctcpOfStream.close();
1104 firstTcpThroughputOfStream.close();
1105 if (enableSecondTcp)
1107 secondTcpCwndOfStream.close();
1108 secondTcpRttOfStream.close();
1109 secondTcpThroughputOfStream.close();
1110 if (secondTcpType ==
"dctcp")
1112 secondTcpDctcpOfStream.close();
1115 queueDropOfStream.close();
1116 queueMarkOfStream.close();
1117 queueMarksFrequencyOfStream.close();
1118 queueLengthOfStream.close();
a polymophic address class
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.
uint64_t GetBitRate() const
Get the underlying bitrate.
Hold variables of type enum.
static TypeId GetTypeId()
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.
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
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() const
Get a pointer to the requested aggregated Object.
uint32_t GetSize() 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.
static TypeId GetTypeId()
Get the type ID.
Create a ping application and associate it to a node.
This application behaves similarly to the Unix ping application, although with fewer options supporte...
Build a set of PointToPointNetDevice objects.
A Device for a Point to Point Network Link.
Class for representing queue sizes.
static TypeId GetTypeId()
Get the type ID.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
static Time Now()
Return the current simulation virtual time.
static void Run()
Run the simulation.
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Hold variables of type string.
static TypeId GetTypeId()
Get the type ID.
static TypeId GetTypeId()
Get the type ID.
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.
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
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.
std::string GetName() const
Get the name.
Hold an unsigned integer type.
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.
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
void(* DataRate)(DataRate oldValue, DataRate newValue)
TracedValue callback signature for DataRate.
Time Now()
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.
void LogComponentEnable(const std::string &name, LogLevel level)
Enable the logging output associated with that log component.
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...
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 TracePingRtt(std::ofstream *ofStream, uint16_t, Time rtt)
Trace ping RTT.
void ScheduleSecondDctcpTraceConnection(std::ofstream *ofStream)
Schedule trace connection.
void TraceMarksFrequency(std::ofstream *ofStream, Time marksSamplingInterval)
Trace marks frequency.
void ScheduleSecondTcpRttTraceConnection(std::ofstream *ofStream)
Schedule trace connection.
void TraceSecondRtt(std::ofstream *ofStream, Time oldRtt, Time newRtt)
Trace second RTT.
void TraceSecondDctcp(std::ofstream *ofStream, uint32_t bytesMarked, uint32_t bytesAcked, double alpha)
Trace second TcpDctcp.
void TraceSecondThroughput(std::ofstream *ofStream, Time throughputInterval)
Trace the second throughput.
void TraceFirstThroughput(std::ofstream *ofStream, Time throughputInterval)
Trace the first throughput.
void ScheduleFirstDctcpTraceConnection(std::ofstream *ofStream)
Schedule trace connection.
void TraceSecondCwnd(std::ofstream *ofStream, uint32_t oldCwnd, uint32_t newCwnd)
Trace second congestion window.
void TraceQueueMark(std::ofstream *ofStream, Ptr< const QueueDiscItem > item, const char *reason)
Trace queue marks.
bool g_validationFailed
True if validation failed.
void ScheduleFirstPacketSinkConnection()
Schedule trace connection.
void TraceQueueLength(std::ofstream *ofStream, DataRate queueLinkRate, uint32_t oldVal, uint32_t newVal)
Trace queue length.
void TraceFirstRx(Ptr< const Packet > packet, const Address &address)
Trace first Rx.
void TraceFirstCwnd(std::ofstream *ofStream, uint32_t oldCwnd, uint32_t newCwnd)
Trace first congestion window.
void TraceQueueDrop(std::ofstream *ofStream, Ptr< const QueueDiscItem > item)
Trace queue drop.
uint32_t g_marksObserved
Number of marked packets observed.
void ScheduleSecondPacketSinkConnection()
Schedule trace connection.
void ScheduleSecondTcpCwndTraceConnection(std::ofstream *ofStream)
Schedule trace connection.
void TraceSecondRx(Ptr< const Packet > packet, const Address &address)
Trace second Rx.
void TraceFirstRtt(std::ofstream *ofStream, Time oldRtt, Time newRtt)
Trace first RTT.
uint32_t g_firstBytesReceived
First received packet size.
std::string g_validate
Empty string disables validation.
uint32_t g_secondBytesReceived
Second received packet size.
uint32_t g_dropsObserved
Number of dropped packets observed.
void TraceFirstDctcp(std::ofstream *ofStream, uint32_t bytesMarked, uint32_t bytesAcked, double alpha)
Trace first TcpDctcp.
void ScheduleFirstTcpRttTraceConnection(std::ofstream *ofStream)
Schedule trace connection.
void ScheduleFirstTcpCwndTraceConnection(std::ofstream *ofStream)
Schedule trace connection.