Can not select TCP congestion control variant

1,737 views
Skip to first unread message

Mauro Vidotto

unread,
Jul 4, 2011, 8:09:09 PM7/4/11
to ns-3-users
Hi all,

I am a new ns3 user.
I am trying to use NS-3 to test different TCP congestion control
algorithms.
I was trying to use the following lines of code that are in the manual
of NS version 3.10 (page 130, section 5.6.2 ns-3 TCP) to select the
one of the variants of TCP congestion control:

TypeId tid = TypeId::LookupByName ("ns3::TcpTahoe");
Ptr<Socket> localSocket = Socket::CreateSocket (node, tid);

When executing the program I get the following error message:

assert failed. cond="socketFactory != 0", file=../src/node/socket.cc,
line=52
terminate called without an active exception
Command ['/home/mauro/repos/ns-allinone-3.10/ns-3.10/build/debug/
scratch/tcptest5'] terminated with signal SIGIOT. Run it under a
debugger to get more information (./waf --run <program> --command-
template="gdb --args %s <args>").

Did I misinterpret the use of these lines of code? Are the lines shown
in the manual correct?
Is there any other way to select the TCP congestion control version?


Thanks
Mauro Vidotto

Mauro Vidotto

unread,
Jul 6, 2011, 10:58:48 PM7/6/11
to ns-3-...@googlegroups.com
Hi Tom,

Thanks for the fast answer.

I tried to set TCP congestion control variant using the first option you suggested, using the line:

Config::SetDefault ("ns3::TcpL4Protocol::SocketType", "ns3::TcpTahoe");

I got the following error at compilation time:

[mauro@G3N ns-3.10]$ ./waf
Waf: Entering directory `/home/mauro/repos/ns-allinone-3.10/ns-3.10/build'
[1332/1521] cxx: scratch/tcptest6.cc -> build/debug/scratch/tcptest6_3.o
../scratch/tcptest6.cc: In function ‘int main(int, char**)’:                                                                                         
../scratch/tcptest6.cc:182:70: error: invalid initialization of reference of type ‘const ns3::AttributeValue&’ from expression of type ‘const char*’
debug/ns3/config.h:56:6: error: in passing argument 2 of ‘void ns3::Config::SetDefault(std::string, const ns3::AttributeValue&)’
Waf: Leaving directory `/home/mauro/repos/ns-allinone-3.10/ns-3.10/build'
Build failed:  -> task failed (err #1):
        {task: cxx tcptest6.cc -> tcptest6_3.o}

However, checking the examples files (file /repos/ns-allinone-3.10/ns-3.10/examples/tcp/tcp-testcases.cc)
I could see that they use the following lines of code to set TCP congestion control variant (the only difference seems to be the use of the function StringValue() ). Using that lines of code I was able to select TCP congestion control variant successfully:

std::string tcpModel ("ns3::TcpNewReno");

Config::SetDefault ("ns3::TcpL4Protocol::SocketType", StringValue (tcpModel));

I also tested the two other ways you suggested to set tcp congestion control variant  (using Config::Set():) , they worked as you explained in your email.

By the way, I am interested in working with TCP Westwood+ congestion control variant. Do you know if there any implementation of this TCP algorithm for NS3 (As far I know there is only an implementation for NS2  available).


2011/7/6 Tom Henderson <to...@tomh.org>
That documentation is wrong and I don't know how it got that way.  The doxygen documentation for CreateSocket() is also misleading because it says to specify the TypeId of the socket but what is really needed to be passed there is of type SocketFactory, not Socket.  I will fix this.


Is there any other way to select the TCP congestion control version?



The file src/test/ns3tcp/ns3-tcp-loss-test-suite.cc compares Tahoe, Reno, and NewReno.  There, the code effectively does this:

 Config::SetDefault ("ns3::TcpL4Protocol::SocketType", "ns3::TcpTahoe");
 ...
 // create nodes and internet stacks
 ...
 Ptr<Socket>  localSocket = Socket::CreateSocket (node, TcpSocketFactory::GetTypeId ());


However, you have to set this default _before_ you create your nodes and internet stacks, else it will not take effect.

If you want to cause the socket type to be set on the spot, right before you call CreateSocket(), you will need to twiddle the SocketType attribute of the TcpL4Protocol object that exists on that node.  This probably should be done through the attribute system since it is awkward to get a handle to a pointer to the underlying TcpL4Protocol.

Here is one way to do it, using Config::Set():

 // Create and bind the socket...

 TypeId tid = TypeId::LookupByName ("ns3::TcpTahoe");
 Config::Set ("/NodeList/*/$ns3::TcpL4Protocol/SocketType", TypeIdValue (tid));
 Ptr<Socket> localSocket =
   Socket::CreateSocket (n0n1.Get (0), TcpSocketFactory::GetTypeId ());

Here, I passed the "*" wild card so that all sockets are set to Tahoe, not just node 'n0n1.Get (0)'.  If you want to limit it to just the specified node, you would have to do something like:

 // Create and bind the socket...

 TypeId tid = TypeId::LookupByName ("ns3::TcpTahoe");
 std::stringstream nodeId;
 nodeId << n0n1.Get (0)->GetId ();
 std::string specificNode = "/NodeList/" + nodeId.str () + "/$ns3::TcpL4Protocol/SocketType";
 Config::Set (specificNode, TypeIdValue (tid));
 Ptr<Socket> localSocket =
   Socket::CreateSocket (n0n1.Get (0), TcpSocketFactory::GetTypeId ());








--
You received this message because you are subscribed to the Google Groups "ns-3-users" group.
To post to this group, send email to ns-3-...@googlegroups.com.
To unsubscribe from this group, send email to ns-3-users+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/ns-3-users?hl=en.


Tom Henderson

unread,
Jul 7, 2011, 12:06:30 AM7/7/11
to ns-3-...@googlegroups.com
On 07/06/2011 07:58 PM, Mauro Vidotto wrote:
> Hi Tom,
>
> Thanks for the fast answer.
>
> I tried to set TCP congestion control variant using the first option you
> suggested, using the line:
>
> Config::SetDefault ("ns3::TcpL4Protocol::SocketType", "ns3::TcpTahoe");
>
> I got the following error at compilation time:

> [mauro@G3N ns-3.10]$ ./waf
> Waf: Entering directory `/home/mauro/repos/ns-allinone-3.10/ns-3.10/build'
> [1332/1521] cxx: scratch/tcptest6.cc -> build/debug/scratch/tcptest6_3.o

> ../scratch/tcptest6.cc: In function �int main(int, char**)�:


> ../scratch/tcptest6.cc:182:70: error: invalid initialization of

> reference of type �const ns3::AttributeValue&� from expression of type
> �const char*�
> debug/ns3/config.h:56:6: error: in passing argument 2 of �void
> ns3::Config::SetDefault(std::string, const ns3::AttributeValue&)�


> Waf: Leaving directory `/home/mauro/repos/ns-allinone-3.10/ns-3.10/build'
> Build failed: -> task failed (err #1):
> {task: cxx tcptest6.cc -> tcptest6_3.o}
>
> However, checking the examples files (file

> //repos/ns-allinone-3.10/ns-3.10/examples/tcp/tcp-testcases.cc/)


> I could see that they use the following lines of code to set TCP
> congestion control variant (the only difference seems to be the use of
> the function StringValue() ). Using that lines of code I was able to
> select TCP congestion control variant successfully:
>
> std::string tcpModel ("ns3::TcpNewReno");
> Config::SetDefault ("ns3::TcpL4Protocol::SocketType", StringValue
> (tcpModel));

Yes, you are right; I tried to take a shortcut when adapting the code
for the email.

This would also work without the intermediate tcpModel variable.

Config::SetDefault ("ns3::TcpL4Protocol::SocketType", StringValue

("ns3::TcpTahoe"));

>
> I also tested the two other ways you suggested to set tcp congestion
> control variant (using Config::Set():) , they worked as you explained
> in your email.
>
> By the way, I am interested in working with TCP Westwood+ congestion
> control variant. Do you know if there any implementation of this TCP
> algorithm for NS3 (As far I know there is only an implementation for
> NS2 available).

This has been in Linux for some time so, you should be able to use the
NSC implementation and set the sysctl variable appropriately; see an
example in examples/tcp/tcp-nsc-lfn.cc.

- Tom

Mauro Vidotto

unread,
Jul 11, 2011, 7:39:06 PM7/11/11
to ns-3-...@googlegroups.com
Hi Tom,

Thanks for the answer.
Just to confirm, by using NSC I will not be able to:
1- Implement nodes with more than one interface (manual specifies a limitation: "NSC only works on single-interface nodes")?
2- It is not posible to trace Congestion Window value as done in the examples fifth and sixth of the tutorial.

Also, just to know:
I want to evaluate the behaviour/performance of different TCP implementations in a congested network. I want to know if it is possible to change for example the buffer size of intermediate routers. Is there any implementation of AQM (RED) for routers in NS3? Any examples/documentation where I can see how to use it?

Thanks in advance
Mauro Vidotto



2011/7/7 Tom Henderson <to...@tomh.org>
On 07/06/2011 07:58 PM, Mauro Vidotto wrote:
Hi Tom,

Thanks for the fast answer.

I tried to set TCP congestion control variant using the first option you
suggested, using the line:

Config::SetDefault ("ns3::TcpL4Protocol::SocketType", "ns3::TcpTahoe");

I got the following error at compilation time:

[mauro@G3N ns-3.10]$ ./waf
Waf: Entering directory `/home/mauro/repos/ns-allinone-3.10/ns-3.10/build'
[1332/1521] cxx: scratch/tcptest6.cc -> build/debug/scratch/tcptest6_3.o
../scratch/tcptest6.cc: In function ‘int main(int, char**)’:

../scratch/tcptest6.cc:182:70: error: invalid initialization of
reference of type ‘const ns3::AttributeValue&’ from expression of type
‘const char*’
debug/ns3/config.h:56:6: error: in passing argument 2 of ‘void
ns3::Config::SetDefault(std::string, const ns3::AttributeValue&)’

Waf: Leaving directory `/home/mauro/repos/ns-allinone-3.10/ns-3.10/build'
Build failed:  -> task failed (err #1):
        {task: cxx tcptest6.cc -> tcptest6_3.o}

However, checking the examples files (file
//repos/ns-allinone-3.10/ns-3.10/examples/tcp/tcp-testcases.cc/)
I could see that they use the following lines of code to set TCP
congestion control variant (the only difference seems to be the use of
the function StringValue() ). Using that lines of code I was able to
select TCP congestion control variant successfully:

std::string tcpModel ("ns3::TcpNewReno");
Config::SetDefault ("ns3::TcpL4Protocol::SocketType", StringValue
(tcpModel));
Yes, you are right; I tried to take a shortcut when adapting the code for the email.

This would also work without the intermediate tcpModel variable.

Config::SetDefault ("ns3::TcpL4Protocol::SocketType", StringValue ("ns3::TcpTahoe"));



I also tested the two other ways you suggested to set tcp congestion
control variant  (using Config::Set():) , they worked as you explained
in your email.

By the way, I am interested in working with TCP Westwood+ congestion
control variant. Do you know if there any implementation of this TCP
algorithm for NS3 (As far I know there is only an implementation for
NS2  available).

This has been in Linux for some time so, you should be able to use the NSC implementation and set the sysctl variable appropriately; see an example in examples/tcp/tcp-nsc-lfn.cc.

- Tom

Tom Henderson

unread,
Jul 12, 2011, 12:19:12 AM7/12/11
to ns-3-...@googlegroups.com
On Mon, 11 Jul 2011 20:39:06 -0300, Mauro Vidotto
<mauro....@gmail.com>
wrote:
> Hi Tom,
>
> Thanks for the answer.
> Just to confirm, by using NSC I will not be able to:
> 1- Implement nodes with more than one interface (manual specifies a
> limitation: "NSC only works on single-interface nodes")?
> 2- It is not posible to trace Congestion Window value as done in the
> examples fifth and sixth of the tutorial.

Yes, those limitations still exist.

>
> Also, just to know:
> I want to evaluate the behaviour/performance of different TCP
> implementations in a congested network. I want to know if it is possible
to
> change for example the buffer size of intermediate routers. Is there any
> implementation of AQM (RED) for routers in NS3? Any
examples/documentation
> where I can see how to use it?

It is possible to change the buffer size of intermediate routers, but
using FIFO scheduling policy with drop-tail drop policy. There is a RED
implementation in work but I do not think it has progressed yet to the
point of being usable by others; here is a somewhat dated code review:
http://codereview.appspot.com/2405042/

- Tom

Tom Henderson

unread,
Jul 12, 2011, 12:27:06 AM7/12/11
to ns-3-...@googlegroups.com

>
> It is possible to change the buffer size of intermediate routers, but
> using FIFO scheduling policy with drop-tail drop policy. There is a RED
> implementation in work but I do not think it has progressed yet to the
> point of being usable by others; here is a somewhat dated code review:
> http://codereview.appspot.com/2405042/

I should point out also that Click has support for RED although I don't
have first-hand experience with it; see:
http://groups.google.com/group/ns-3-users/browse_thread/thread/db0039684ef7b681/43e908e399c8aa68?lnk=gst&q=RED#43e908e399c8aa68

Tom

Tom Henderson

unread,
Jul 6, 2011, 10:58:37 AM7/6/11
to ns-3-...@googlegroups.com
On 07/04/2011 05:09 PM, Mauro Vidotto wrote:

That documentation is wrong and I don't know how it got that way. The

doxygen documentation for CreateSocket() is also misleading because it
says to specify the TypeId of the socket but what is really needed to be
passed there is of type SocketFactory, not Socket. I will fix this.

> Is there any other way to select the TCP congestion control version?
>
>

The file src/test/ns3tcp/ns3-tcp-loss-test-suite.cc compares Tahoe,

Reno, and NewReno. There, the code effectively does this:

Config::SetDefault ("ns3::TcpL4Protocol::SocketType", "ns3::TcpTahoe");


...
// create nodes and internet stacks
...

Ptr<Socket> localSocket = Socket::CreateSocket (node,

TcpSocketFactory::GetTypeId ());


However, you have to set this default _before_ you create your nodes and
internet stacks, else it will not take effect.

If you want to cause the socket type to be set on the spot, right before
you call CreateSocket(), you will need to twiddle the SocketType
attribute of the TcpL4Protocol object that exists on that node. This
probably should be done through the attribute system since it is awkward
to get a handle to a pointer to the underlying TcpL4Protocol.

Here is one way to do it, using Config::Set():

// Create and bind the socket...

TypeId tid = TypeId::LookupByName ("ns3::TcpTahoe");

Config::Set ("/NodeList/*/$ns3::TcpL4Protocol/SocketType",
TypeIdValue (tid));

Ptr<Socket> localSocket =


Socket::CreateSocket (n0n1.Get (0), TcpSocketFactory::GetTypeId ());

Here, I passed the "*" wild card so that all sockets are set to Tahoe,
not just node 'n0n1.Get (0)'. If you want to limit it to just the
specified node, you would have to do something like:

// Create and bind the socket...

TypeId tid = TypeId::LookupByName ("ns3::TcpTahoe");

std::stringstream nodeId;
nodeId << n0n1.Get (0)->GetId ();
std::string specificNode = "/NodeList/" + nodeId.str () +
"/$ns3::TcpL4Protocol/SocketType";
Config::Set (specificNode, TypeIdValue (tid));

Ptr<Socket> localSocket =

Reply all
Reply to author
Forward
Message has been deleted
0 new messages