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));
 
  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
AttributeValue implementation for Address.
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.
AttributeValue implementation for Boolean.
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.
AttributeValue implementation for DataRate.
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...
@ SILENT
Silent output (no terminal output at all).
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.
AttributeValue implementation for QueueSize.
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.
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.
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.
AttributeValue implementation for TypeId.
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.