How to track Congestion Window in wireless examples

309 views
Skip to first unread message

Tenusha Guruge

unread,
May 9, 2020, 6:21:32 AM5/9/20
to ns-3-users
I have modified the wifi-tcp as follows. I need to track the Congestion Window as I'm testing the modifications done to a new TCP variation that I'm developing.

Enter code here.../* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
 
/*
  * Copyright (c) 2015, IMDEA Networks Institute
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation;
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Hany Assasa <hany....@gmail.com>
 .*
  * This is a simple example to test TCP over 802.11n (with MPDU aggregation enabled).
  *
  * Network topology:
  *
  *   Ap    STA
  *   *      *
  *   |      |
  *   n1     n2
  *
  * In this example, an HT station sends TCP packets to the access point.
  * We report the total throughput received during a window of 100ms.
  * The user can specify the application data rate and choose the variant
  * of TCP i.e. congestion control algorithm to use.
  */

 
 
#include "ns3/command-line.h"
 
#include "ns3/config.h"
 
#include "ns3/string.h"
 
#include "ns3/log.h"
 
#include "ns3/yans-wifi-helper.h"
 
#include "ns3/ssid.h"
 
#include "ns3/mobility-helper.h"
 
#include "ns3/on-off-helper.h"
 
#include "ns3/yans-wifi-channel.h"
 
#include "ns3/mobility-model.h"
 
#include "ns3/packet-sink.h"
 
#include "ns3/packet-sink-helper.h"
 
#include "ns3/tcp-westwood.h"
 
#include "ns3/internet-stack-helper.h"
 
#include "ns3/ipv4-address-helper.h"
 
#include "ns3/point-to-point-module.h"
 
#include "ns3/ipv4-global-routing-helper.h"
 
 NS_LOG_COMPONENT_DEFINE
("wifi-tcp");
 
 
using namespace ns3;
 
 
Ptr<PacketSink> sink;                         /* Pointer to the packet sink application */
 uint64_t lastTotalRx
= 0;                     /* The value of the last total received bytes */
 
 
void
 
CalculateThroughput ()
 
{
   
Time now = Simulator::Now ();                                         /* Return the simulator's virtual time. */
   
double cur = (sink->GetTotalRx () - lastTotalRx) * (double) 8 / 1e5;     /* Convert Application RX Packets to MBits. */
   std
::cout << now.GetSeconds () << "s: \t" << cur << " Mbit/s" << std::endl;
   lastTotalRx
= sink->GetTotalRx ();
   
Simulator::Schedule (MilliSeconds (100), &CalculateThroughput);
 
}
 
 
static void
 
CwndTracer(Ptr <OutputStreamWrapper> stream, uint32_t oldval, uint32_t newval) {
   
// NS_LOG_INFO ("Moving cwnd from " << oldval << " to " << newval);
   NS_LOG_UNCOND
(Simulator::Now().GetSeconds() << "\t" << newval);
   
* stream -> GetStream() << Simulator::Now().GetSeconds() << "\t" << oldval << "\t" << newval << std::endl;
 
}
 
 
int
 main
(int argc, char *argv[])
 
{
     
   
// LogComponentEnable("Emtp", LOG_LEVEL_ALL);
   
// LogComponentEnable("NodeList", LOG_LEVEL_ALL);
   
   
   uint32_t payloadSize
= 1472;                       /* Transport layer payload size in bytes. */
   std
::string dataRate = "100Mbps";                  /* Application layer datarate. */
   std
::string tcpVariant = "Emtp";             /* TCP variant type. */
   std
::string phyRate = "HtMcs7";                    /* Physical layer bitrate. */
   
double simulationTime = 10;                        /* Simulation time in seconds. */
   
bool pcapTracing = false;                          /* PCAP Tracing is enabled or not. */
 
   
/* Command line argument parser setup. */
   
CommandLine cmd;
   cmd
.AddValue ("payloadSize", "Payload size in bytes", payloadSize);
   cmd
.AddValue ("dataRate", "Application data ate", dataRate);
   cmd
.AddValue ("tcpVariant", "Transport protocol to use: Emtp, "
                 
"TcpHybla, TcpHighSpeed, TcpHtcp, TcpVegas, TcpScalable, TcpVeno, "
                 
"TcpBic, TcpYeah, TcpIllinois, TcpWestwood, TcpWestwoodPlus, TcpLedbat ", tcpVariant);
   cmd
.AddValue ("phyRate", "Physical layer bitrate", phyRate);
   cmd
.AddValue ("simulationTime", "Simulation time in seconds", simulationTime);
   cmd
.AddValue ("pcap", "Enable/disable PCAP Tracing", pcapTracing);
   cmd
.Parse (argc, argv);
 
   tcpVariant
= std::string ("ns3::") + tcpVariant;
   
// Select TCP variant
   
if (tcpVariant.compare ("ns3::TcpWestwoodPlus") == 0)
     
{
       
// TcpWestwoodPlus is not an actual TypeId name; we need TcpWestwood here
       
Config::SetDefault ("ns3::TcpL4Protocol::SocketType", TypeIdValue (TcpWestwood::GetTypeId ()));
       
// the default protocol type in ns3::TcpWestwood is WESTWOOD
       
Config::SetDefault ("ns3::TcpWestwood::ProtocolType", EnumValue (TcpWestwood::WESTWOODPLUS));
     
}
   
else
     
{
       
TypeId tcpTid;
       NS_ABORT_MSG_UNLESS
(TypeId::LookupByNameFailSafe (tcpVariant, &tcpTid), "TypeId " << tcpVariant << " not found");
       
Config::SetDefault ("ns3::TcpL4Protocol::SocketType", TypeIdValue (TypeId::LookupByName (tcpVariant)));
     
}
 
   
/* Configure TCP Options */
   
Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (payloadSize));
 
   
WifiMacHelper wifiMac;
   
WifiHelper wifiHelper;
   wifiHelper
.SetStandard (WIFI_PHY_STANDARD_80211n_5GHZ);
 
   
/* Set up Legacy Channel */
   
YansWifiChannelHelper wifiChannel;
   wifiChannel
.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
   wifiChannel
.AddPropagationLoss ("ns3::FriisPropagationLossModel", "Frequency", DoubleValue (5e9));
 
   
/* Setup Physical Layer */
   
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
   wifiPhy
.SetChannel (wifiChannel.Create ());
   wifiPhy
.SetErrorRateModel ("ns3::YansErrorRateModel");
   wifiHelper
.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
                                       
"DataMode", StringValue (phyRate),
                                       
"ControlMode", StringValue ("HtMcs0"));
 
   
NodeContainer firstNetworkNodes;
   firstNetworkNodes
.Create (2);
   
   
NodeContainer secondNetworkNodes;
   secondNetworkNodes
.Create (2);
   
   
NodeContainer middleNetworkNodes;
   middleNetworkNodes
.Add (firstNetworkNodes.Get (1));
   middleNetworkNodes
.Add (secondNetworkNodes.Get (0));
   
   
PointToPointHelper p2p;
   p2p
.SetDeviceAttribute ("DataRate", DataRateValue (DataRate (10000000)));
   p2p
.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (10)));
   
   
NetDeviceContainer middleDeviceContainer = p2p.Install (middleNetworkNodes);
   
   
Ptr<Node> apWifiNode = firstNetworkNodes.Get (1);
   
Ptr<Node> staWifiNode = firstNetworkNodes.Get (0);
 
   
Ptr<Node> apWifiNode2 = secondNetworkNodes.Get (0);
   
Ptr<Node> staWifiNode2 = secondNetworkNodes.Get (1);
   
   
/* Configure AP */
   
Ssid ssid = Ssid ("network");
   wifiMac
.SetType ("ns3::ApWifiMac", "Ssid", SsidValue (ssid));
 
   
NetDeviceContainer apDevice;
   apDevice
= wifiHelper.Install (wifiPhy, wifiMac, apWifiNode);
 
   
/* Configure STA */
   wifiMac
.SetType ("ns3::StaWifiMac", "Ssid", SsidValue (ssid));
 
   
NetDeviceContainer staDevices;
   staDevices
= wifiHelper.Install (wifiPhy, wifiMac, staWifiNode);

   
// Second network
   wifiPhy
.SetChannel (wifiChannel.Create ());

   wifiMac
.SetType ("ns3::ApWifiMac", "Ssid", SsidValue (ssid));
 
   
NetDeviceContainer apDevice2;
   apDevice2
= wifiHelper.Install (wifiPhy, wifiMac, apWifiNode2);

   wifiMac
.SetType ("ns3::StaWifiMac", "Ssid", SsidValue (ssid));
 
   
NetDeviceContainer staDevices2;
   staDevices2
= wifiHelper.Install (wifiPhy, wifiMac, staWifiNode2);


   
/* Mobility model */
   
MobilityHelper mobility;
   
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
   positionAlloc
->Add (Vector (0.0, 0.0, 0.0));
   positionAlloc
->Add (Vector (1.0, 1.0, 0.0));
 
   mobility
.SetPositionAllocator (positionAlloc);
   mobility
.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
   mobility
.Install (apWifiNode);
   mobility
.Install (staWifiNode);

   mobility
.Install (apWifiNode2);
   mobility
.Install (staWifiNode2);
 
   
/* Internet stack */
   
InternetStackHelper stack;
   stack
.Install (firstNetworkNodes);
   stack
.Install (secondNetworkNodes);
 
   
Ipv4AddressHelper address;
   address
.SetBase ("10.1.1.0", "255.255.255.0");
   
Ipv4InterfaceContainer apInterface;
   apInterface
= address.Assign (apDevice);
   
Ipv4InterfaceContainer staInterface;
   staInterface
= address.Assign (staDevices);
 
   address
.SetBase ("10.1.2.0", "255.255.255.0");
   
Ipv4InterfaceContainer apInterface2;
   apInterface2
= address.Assign (apDevice2);
   
Ipv4InterfaceContainer staInterface2;
   staInterface2
= address.Assign (staDevices2);

   address
.SetBase ("10.1.3.0", "255.255.255.0");
   
Ipv4InterfaceContainer midDevInterface;
   midDevInterface
= address.Assign (middleDeviceContainer);
 
   
/* Populate routing table */
   
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
 
   
/* Install TCP Receiver on the access point */
   
PacketSinkHelper sinkHelper ("ns3::TcpSocketFactory", InetSocketAddress (staInterface2.GetAddress (0), 9));
   
ApplicationContainer sinkApp = sinkHelper.Install (staWifiNode2);
   sink
= StaticCast<PacketSink> (sinkApp.Get (0));
 
   
/* Install TCP/UDP Transmitter on the station */
   
OnOffHelper server ("ns3::TcpSocketFactory", (InetSocketAddress (staInterface2.GetAddress (0), 9)));
   server
.SetAttribute ("PacketSize", UintegerValue (payloadSize));
   server
.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
   server
.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
   server
.SetAttribute ("DataRate", DataRateValue (DataRate (dataRate)));
   
ApplicationContainer serverApp = server.Install (staWifiNode);
 
   
/* Start Applications */
   sinkApp
.Start (Seconds (0.0));
   serverApp
.Start (Seconds (1.0));
   
   
AsciiTraceHelper asciiTraceHelper;
   
Ptr <OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream("emtp-low-frequency-transfer.cwnd");
   
Config::ConnectWithoutContext ("/NodeList/*/$ns3::TcpL4Protocol/SocketList/*/CongestionWindow", MakeBoundCallback (&CwndTracer, stream));
 
   
Simulator::Schedule (Seconds (1.1), &CalculateThroughput);
 
   
/* Enable Traces */
   
if (pcapTracing)
     
{
       wifiPhy
.SetPcapDataLinkType (WifiPhyHelper::DLT_IEEE802_11_RADIO);
       wifiPhy
.EnablePcap ("AccessPoint", apDevice);
       wifiPhy
.EnablePcap ("Station", staDevices);
     
}
 
   
/* Start Simulation */
   
Simulator::Stop (Seconds (simulationTime + 1));
   
Simulator::Run ();
 
   
double averageThroughput = ((sink->GetTotalRx () * 8) / (1e6 * simulationTime));
 
   
Simulator::Destroy ();
 
   
if (averageThroughput < 5)
     
{
       NS_LOG_ERROR
("Obtained throughput is not in the expected boundaries!");
       
exit (1);
     
}
   std
::cout << "\nAverage throughput: " << averageThroughput << " Mbit/s" << std::endl;
   
return 0;
 
}


I have tried different methods to trace the cwnd, but nothing is working. I have used tcp-large-transfer example and it's working fine. I can track the cwnd in that example. There is no issue in the new protocol that I'm testing

Hannah Schultz

unread,
Feb 13, 2022, 6:36:24 PM2/13/22
to ns-3-users
I am having the same issue - were you able to resolve this?

Soulimane Mammar

unread,
Feb 14, 2022, 6:12:23 PM2/14/22
to ns-3-users
When you say nothing is working, what do you mean?
Are you getting an empty file at the end of the simulation ?

Hannah Schultz

unread,
Feb 14, 2022, 7:14:08 PM2/14/22
to ns-3-users
Using another example - I get a file with 2 data points at the end of the simulation.

Hannah Schultz

unread,
Feb 14, 2022, 7:21:52 PM2/14/22
to ns-3-users
static void
CwndTracer (uint32_t oldval, uint32_t newval)
{
if (firstCwnd)
{
*cWndStream->GetStream () << "0.0 " << oldval << std::endl;
firstCwnd = false;
}
*cWndStream->GetStream () << Simulator::Now ().GetSeconds () << " " << newval << std::endl;
cWndValue = newval;
if (!firstSshThr)
{
*ssThreshStream->GetStream () << Simulator::Now ().GetSeconds () << " " << ssThreshValue << std::endl;
}
}

static void
TraceCwnd (std::string cwnd_tr_file_name)
{
AsciiTraceHelper ascii;
cWndStream = ascii.CreateFileStream (cwnd_tr_file_name.c_str ());
Config::ConnectWithoutContext ("/NodeList/*/$ns3::TcpL4Protocol/SocketList/*/CongestionWindow", MakeCallback (&CwndTracer));
}

. . .

Simulator::Schedule (Seconds (0.1), &TraceCwnd, "NR-cwnd.csv");

Soulimane Mammar

unread,
Feb 15, 2022, 6:29:25 PM2/15/22
to ns-3-users
Hi,
I took a look to your senario and the line
Config::ConnectWithoutContext ("/NodeList/*/$ns3::TcpL4Protocol/SocketList/*/CongestionWindow", MakeBoundCallback (&CwndTracer, stream));
is problematic since the config path of the different TCP variants are different and in some cases the trace source CongestionWindow is not even available.
For instance, TcpVeno, TcpVegas, and TcpWestwood do not have the trace source CongestionWindow and they have different config path

I'm using ns3-33, I don't know if it is different from the version you are using, I also noticed that you are using some code that is either deprecated or not working at all in newer version of ns3 such as YansWifiPhyHelper::Default () ;
Regards

Hannah Schultz

unread,
Feb 15, 2022, 6:36:04 PM2/15/22
to ns-3-users
Thanks! 

How do I find the config path? 

I am using 3.34

Soulimane Mammar

unread,
Feb 15, 2022, 6:46:12 PM2/15/22
to ns-3-users
Hi,
If you want to know about the config paths, attributes, trace sources,  just visit the web page of the corresponding class
For instance if you visit https://www.nsnam.org/doxygen/classns3_1_1_tcp_veno.html#details, you'll find all the information you need about TcpVeno
Regards

Li, Ye

unread,
Feb 15, 2022, 8:10:14 PM2/15/22
to ns-3-...@googlegroups.com
Another method to figure out the config paths is to output all the configs of the objects to a file. Like this:

// Output default attributes
Config::SetDefault ("ns3::ConfigStore::Filename", StringValue ("sim-attributes.xml"));
Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Save"));
ConfigStore outputConfig;
outputConfig.ConfigureAttributes ();




You will see strings like these in the file:
    
    value /$ns3::NodeListPriv/NodeList/3/$ns3::Node/$ns3::TcpL4Protocol/RttEstimatorType "ns3::RttMeanDeviation"
    value /$ns3::NodeListPriv/NodeList/3/$ns3::Node/$ns3::TcpL4Protocol/SocketType "ns3::TcpNewReno"
    value /$ns3::NodeListPriv/NodeList/3/$ns3::Node/$ns3::TcpL4Protocol/RecoveryType "ns3::TcpPrrRecovery"

These will give you hints on the node IDs, object names/positions in the corresponding config paths.

--
Posting to this group should follow these guidelines https://www.nsnam.org/wiki/Ns-3-users-guidelines-for-posting
---
You received this message because you are subscribed to the Google Groups "ns-3-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ns-3-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ns-3-users/1bf1829a-09b8-4e81-9463-dba099f22e83n%40googlegroups.com.


--
LI, Ye
School of Information Science and Technology
Nantong University
Nantong 226019, Jiangsu Province, China

Hannah Schultz

unread,
Feb 16, 2022, 10:11:09 AM2/16/22
to ns-3-users
Thank you for all your help! 

When I use this path: /NodeList/*/$ns3::TcpL4Protocol/SocketList/*/CongestionOps the callback cannot connect.

I am still stuck with this. Any more help would be greatly appreciated.

Soulimane Mammar

unread,
Feb 16, 2022, 10:47:56 AM2/16/22
to ns-3-users
Hi,
Because this path doesn't exist for all Tcp variants. TcpWestwood can indeed be configured/traced with this path, but unfortunately for you, it doesn't have a trace source named "CongestionWindow "
Regards

Ayub Afridi

unread,
Feb 16, 2022, 10:54:33 AM2/16/22
to ns-3-...@googlegroups.com
please tell me what is this error?
Program received signal SIGSEGV, Segmentation fault.
0x000055555556f206 in ns3::PeekPointer<ns3::Node> (p=...) at ./ns3/ptr.h:413

Ayub Afridi

unread,
Feb 16, 2022, 10:57:10 AM2/16/22
to ns-3-...@googlegroups.com
Program received signal SIGSEGV, Segmentation fault.
0x000055555556f206 in ns3::PeekPointer<ns3::Node> (p=...) at ./ns3/ptr.h:413

On Wed, Feb 16, 2022 at 4:48 PM Soulimane Mammar <souliman...@gmail.com> wrote:
Message has been deleted

Hannah Schultz

unread,
Feb 16, 2022, 12:00:16 PM2/16/22
to ns-3-users
But this occurs even with TCP variants that have a CwndEvent trace, such as BBR

msg="Could not connect callback to /NodeList/0/$ns3::TcpL4Protocol/SocketList/0/CongestionOps/$ns3::TcpBbr", +0.100000000s -1 file=../src/core/model/config.cc, line=906

libc++abi.dylib: terminating


Soulimane Mammar

unread,
Feb 16, 2022, 5:26:29 PM2/16/22
to ns-3-users
Hi,
If you take a look at https://www.nsnam.org/doxygen/classns3_1_1_tcp_bbr.html#details you'll se that TcpBbr has no trace sources, so it's normal that you can't connect to a trace source that doesn't exist
Regards

Hannah Schultz

unread,
Feb 16, 2022, 5:36:23 PM2/16/22
to ns-3-users
So essentially, I can't track a congestion window for any wireless implementation on any variant?

Soulimane Mammar

unread,
Feb 16, 2022, 6:02:33 PM2/16/22
to ns-3-users
Hi,
For those where the CongestionWindow trace source exist you can, for the others no unless you add them by yourself (adding code to existing implementations)
Regards

Hannah Schultz

unread,
Feb 16, 2022, 6:47:14 PM2/16/22
to ns-3-users
Thanks for all your help!
Reply all
Reply to author
Forward
0 new messages