120#include "ns3/applications-module.h"
121#include "ns3/core-module.h"
122#include "ns3/internet-apps-module.h"
123#include "ns3/internet-module.h"
124#include "ns3/network-module.h"
125#include "ns3/point-to-point-module.h"
126#include "ns3/traffic-control-module.h"
166 double cwnd =
static_cast<double>(newCwnd) / 1448;
167 if ((now > 5.43) && (now < 5.465) && (cwnd < 500))
172 else if ((now > 5.795) && (now < 6) && (cwnd > 190))
177 else if ((now > 14) && (now < 14.197) && (cwnd < 224))
182 else if ((now > 17) && (now < 18.026) && (cwnd < 212))
209 if ((now < 7.5) && (alpha < 0.1))
214 else if ((now > 11) && (now < 30) && (alpha > 0.01))
219 else if ((now > 34) && (alpha < 0.015) && (alpha > 0.025))
222 <<
" (expected 0.015 <= alpha <= 0.025)");
229 if ((now > 5.6) && (alpha > 0.1))
234 if ((now > 7) && ((alpha > 0.09) || (alpha < 0.049)))
237 <<
" (expected 0.09 <= alpha <= 0.049)");
400 <<
static_cast<double>(newVal * 8) / (queueLinkRate.
GetBitRate() / 1000)
422 marksSamplingInterval);
447 <<
" (expected <= 20)");
453 <<
" (expected <= 48)");
459 <<
" (expected 47.5 <= throughput <= 48.5)");
469 <<
" (expected 48 <= throughput <= 49)");
502 "/NodeList/1/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow",
527 "CongestionOps/$ns3::TcpDctcp/CongestionEstimate",
540 "CongestionOps/$ns3::TcpDctcp/CongestionEstimate",
589main(
int argc,
char* argv[])
595 bool enableSecondTcp =
false;
596 bool enableLogging =
false;
600 std::string pingTraceFile =
"tcp-validation-ping.dat";
601 std::string firstTcpRttTraceFile =
"tcp-validation-first-tcp-rtt.dat";
602 std::string firstTcpCwndTraceFile =
"tcp-validation-first-tcp-cwnd.dat";
603 std::string firstDctcpTraceFile =
"tcp-validation-first-dctcp-alpha.dat";
604 std::string firstTcpThroughputTraceFile =
"tcp-validation-first-tcp-throughput.dat";
605 std::string secondTcpRttTraceFile =
"tcp-validation-second-tcp-rtt.dat";
606 std::string secondTcpCwndTraceFile =
"tcp-validation-second-tcp-cwnd.dat";
607 std::string secondTcpThroughputTraceFile =
"tcp-validation-second-tcp-throughput.dat";
608 std::string secondDctcpTraceFile =
"tcp-validation-second-dctcp-alpha.dat";
609 std::string queueMarkTraceFile =
"tcp-validation-queue-mark.dat";
610 std::string queueDropTraceFile =
"tcp-validation-queue-drop.dat";
611 std::string queueMarksFrequencyTraceFile =
"tcp-validation-queue-marks-frequency.dat";
612 std::string queueLengthTraceFile =
"tcp-validation-queue-length.dat";
617 std::string firstTcpType =
"cubic";
618 std::string secondTcpType =
"";
619 std::string queueType =
"codel";
623 bool queueUseEcn =
false;
625 bool enablePcap =
false;
647 cmd.AddValue(
"firstTcpType",
"first TCP type (cubic, dctcp, or reno)", firstTcpType);
648 cmd.AddValue(
"secondTcpType",
"second TCP type (cubic, dctcp, or reno)", secondTcpType);
649 cmd.AddValue(
"queueType",
"bottleneck queue type (fq, codel, pie, or red)", queueType);
650 cmd.AddValue(
"baseRtt",
"base RTT", baseRtt);
651 cmd.AddValue(
"ceThreshold",
"CoDel CE threshold (for DCTCP)", ceThreshold);
652 cmd.AddValue(
"linkRate",
"data rate of bottleneck link", linkRate);
653 cmd.AddValue(
"stopTime",
"simulation stop time",
stopTime);
654 cmd.AddValue(
"queueUseEcn",
"use ECN on queue", queueUseEcn);
655 cmd.AddValue(
"enablePcap",
"enable Pcap", enablePcap);
656 cmd.AddValue(
"validate",
"validation case to run",
g_validate);
657 cmd.Parse(argc, argv);
709 Time oneWayDelay = baseRtt / 2;
712 if (firstTcpType ==
"reno")
716 else if (firstTcpType ==
"cubic")
720 else if (firstTcpType ==
"dctcp")
727 std::cout <<
"Warning: using DCTCP with queue ECN disabled" << std::endl;
735 if (secondTcpType ==
"reno")
737 enableSecondTcp =
true;
740 else if (secondTcpType ==
"cubic")
742 enableSecondTcp =
true;
745 else if (secondTcpType ==
"dctcp")
747 enableSecondTcp =
true;
750 else if (secondTcpType.empty())
752 enableSecondTcp =
false;
760 if (queueType ==
"fq")
764 else if (queueType ==
"codel")
768 else if (queueType ==
"pie")
772 else if (queueType ==
"red")
795 <<
"; second TCP: " << secondTcpTypeId.
GetName()
796 <<
"; queue: " << queueTypeId.
GetName()
797 <<
"; ceThreshold: " << ceThreshold.
GetSeconds() * 1000 <<
"ms");
802 <<
"; queue: " << queueTypeId.
GetName()
803 <<
"; ceThreshold: " << ceThreshold.
GetSeconds() * 1000 <<
"ms");
807 std::ofstream pingOfStream;
808 std::ofstream firstTcpRttOfStream;
809 std::ofstream firstTcpCwndOfStream;
810 std::ofstream firstTcpThroughputOfStream;
811 std::ofstream firstTcpDctcpOfStream;
812 std::ofstream secondTcpRttOfStream;
813 std::ofstream secondTcpCwndOfStream;
814 std::ofstream secondTcpThroughputOfStream;
815 std::ofstream secondTcpDctcpOfStream;
816 std::ofstream queueDropOfStream;
817 std::ofstream queueMarkOfStream;
818 std::ofstream queueMarksFrequencyOfStream;
819 std::ofstream queueLengthOfStream;
822 pingOfStream.open(pingTraceFile, std::ofstream::out);
823 firstTcpRttOfStream.open(firstTcpRttTraceFile, std::ofstream::out);
824 firstTcpCwndOfStream.open(firstTcpCwndTraceFile, std::ofstream::out);
825 firstTcpThroughputOfStream.open(firstTcpThroughputTraceFile, std::ofstream::out);
826 if (firstTcpType ==
"dctcp")
828 firstTcpDctcpOfStream.open(firstDctcpTraceFile, std::ofstream::out);
832 secondTcpRttOfStream.open(secondTcpRttTraceFile, std::ofstream::out);
833 secondTcpCwndOfStream.open(secondTcpCwndTraceFile, std::ofstream::out);
834 secondTcpThroughputOfStream.open(secondTcpThroughputTraceFile, std::ofstream::out);
835 if (secondTcpType ==
"dctcp")
837 secondTcpDctcpOfStream.open(secondDctcpTraceFile, std::ofstream::out);
840 queueDropOfStream.open(queueDropTraceFile, std::ofstream::out);
841 queueMarkOfStream.open(queueMarkTraceFile, std::ofstream::out);
842 queueMarksFrequencyOfStream.open(queueMarksFrequencyTraceFile, std::ofstream::out);
843 queueLengthOfStream.open(queueLengthTraceFile, std::ofstream::out);
872 pingServerDevices =
p2p.Install(wanRouter, pingServer);
873 firstServerDevices =
p2p.Install(wanRouter, firstServer);
874 secondServerDevices =
p2p.Install(wanRouter, secondServer);
875 p2p.SetChannelAttribute(
"Delay",
TimeValue(oneWayDelay));
876 wanLanDevices =
p2p.Install(wanRouter, lanRouter);
879 pingClientDevices =
p2p.Install(lanRouter, pingClient);
880 firstClientDevices =
p2p.Install(lanRouter, firstClient);
881 secondClientDevices =
p2p.Install(lanRouter, secondClient);
888 stackHelper.
Install(pingServer);
890 stackHelper.
Install(firstServer);
892 proto->SetAttribute(
"SocketType",
TypeIdValue(firstTcpTypeId));
893 stackHelper.
Install(secondServer);
894 stackHelper.
Install(wanRouter);
895 stackHelper.
Install(lanRouter);
896 stackHelper.
Install(pingClient);
898 stackHelper.
Install(firstClient);
901 proto->SetAttribute(
"SocketType",
TypeIdValue(firstTcpTypeId));
902 stackHelper.
Install(secondClient);
907 proto->SetAttribute(
"SocketType",
TypeIdValue(secondTcpTypeId));
909 proto->SetAttribute(
"SocketType",
TypeIdValue(secondTcpTypeId));
920 tchFq.
Install(pingServerDevices);
921 tchFq.
Install(firstServerDevices);
922 tchFq.
Install(secondServerDevices);
924 tchFq.
Install(pingClientDevices);
925 tchFq.
Install(firstClientDevices);
926 tchFq.
Install(secondClientDevices);
934 ipv4.SetBase(
"10.1.1.0",
"255.255.255.0");
936 ipv4.SetBase(
"10.1.2.0",
"255.255.255.0");
938 ipv4.SetBase(
"10.1.3.0",
"255.255.255.0");
940 ipv4.SetBase(
"172.16.1.0",
"255.255.255.0");
942 ipv4.SetBase(
"192.168.1.0",
"255.255.255.0");
944 ipv4.SetBase(
"192.168.2.0",
"255.255.255.0");
946 ipv4.SetBase(
"192.168.3.0",
"255.255.255.0");
955 pingHelper.SetAttribute(
"Interval",
TimeValue(pingInterval));
957 pingHelper.SetAttribute(
"VerboseMode",
EnumValue(Ping::VerboseMode::SILENT));
965 uint16_t firstPort = 5000;
971 tcp.SetAttribute(
"Remote",
AddressValue(firstDestAddress));
972 firstApp = tcp.Install(firstServer);
978 PacketSinkHelper firstSinkHelper(
"ns3::TcpSocketFactory", firstSinkAddress);
979 firstSinkApp = firstSinkHelper.Install(firstClient);
987 uint16_t secondPort = 5000;
990 tcp.SetAttribute(
"Remote",
AddressValue(secondDestAddress));
991 secondApp = tcp.Install(secondServer);
996 PacketSinkHelper secondSinkHelper(
"ns3::TcpSocketFactory", secondSinkAddress);
998 secondSinkApp = secondSinkHelper.Install(secondClient);
1008 qd = tc->GetRootQueueDiscOnDevice(wanLanDevices.
Get(0));
1018 &firstTcpRttOfStream);
1021 &firstTcpCwndOfStream);
1023 if (firstTcpType ==
"dctcp")
1027 &firstTcpDctcpOfStream);
1031 &firstTcpThroughputOfStream,
1032 throughputSamplingInterval);
1033 if (enableSecondTcp)
1038 &secondTcpRttOfStream);
1041 &secondTcpCwndOfStream);
1045 &secondTcpThroughputOfStream,
1046 throughputSamplingInterval);
1047 if (secondTcpType ==
"dctcp")
1051 &secondTcpDctcpOfStream);
1056 &queueMarksFrequencyOfStream,
1057 marksSamplingInterval);
1061 p2p.EnablePcapAll(
"tcp-validation",
false);
1070 pingOfStream.close();
1071 firstTcpCwndOfStream.close();
1072 firstTcpRttOfStream.close();
1073 if (firstTcpType ==
"dctcp")
1075 firstTcpDctcpOfStream.close();
1077 firstTcpThroughputOfStream.close();
1078 if (enableSecondTcp)
1080 secondTcpCwndOfStream.close();
1081 secondTcpRttOfStream.close();
1082 secondTcpThroughputOfStream.close();
1083 if (secondTcpType ==
"dctcp")
1085 secondTcpDctcpOfStream.close();
1088 queueDropOfStream.close();
1089 queueMarkOfStream.close();
1090 queueMarksFrequencyOfStream.close();
1091 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.
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.
Smart pointer class similar to boost::intrusive_ptr.
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.
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
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.