Understand the difference among the sockets (Ipv4RawSocketFactory vs UdpSocketFactory)

322 views
Skip to first unread message

Matteo Danieletto

unread,
Aug 4, 2015, 2:37:48 PM8/4/15
to ns-3-users
Hi all,
I would like to understand little more about the difference among the sockets that I can use. I am asking because I have some doubt about how I can use them.
 
Example:
Address remoteAddress =  InetSocketAddress (interfaces.GetAddress (idSinkNode), port);
OnOffHelper sender ("ns3::Ipv4RawSocketFactory", remoteAddress);

sender.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1.0]"));
sender.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0.0]"));
ApplicationContainer senderapps = sender.Install (nodes.Get (idTxNode));
senderapps.Start (Seconds (20.0));
senderapps.Stop (Seconds (TotalTime));

NS_LOG_INFO ("Create Sink");
PacketSinkHelper receiver1 = PacketSinkHelper ("ns3::Ipv4RawSocketFactory", InetSocketAddress (interfaces.GetAddress (idSinkNode)));
ApplicationContainer receiverapp1 =receiver1.Install(nodes.Get (idSinkNode));

std::string senderNodeConfig = "/NodeList/"+to_string(idTxNode)+"/ApplicationList/*/$ns3::OnOffApplication/Tx";
Config::Connect("/NodeList/*/ApplicationList/0/$ns3::PacketSink/Rx", MakeCallback(&SinkRx));

where the callback function is:

int packetRXCount = 0;
static void SinkRx ( std::string context, Ptr<const Packet> p, const Address &ad)
{
packetRXCount++;
std::cout << Simulator::Now().GetSeconds()<< " " << context << std::endl;
}

The callback is always fired when I received a packet.

But when I created the PacketSinkHelper with "ns3::UdpSocketFactory"  the callback is never fired. 
I tried to understand something more into doxygen documentation but I didn't find nothing interesting.

Thank you
Matteo

Tommaso Pecorella

unread,
Aug 4, 2015, 4:48:01 PM8/4/15
to ns-3-users
Hi,

Ipv[4.6]RawSockets are equivalent to an IP RAW socket (NSS) see also http://linux.die.net/man/7/raw
UdpSocket is... UDP. Again, NSS.

The main difference is that an UdpSocket will have a sender and destination port, and the packets will have an UDP header. In order to receive an UDP packet, of course, the sender will have to match exactly the receiver port.

An IP raw socket is totally different. It does have just the IP header, and nothing more. The receiving end will have to figure out everything, and it could receive also "unwanted" things. E.g., your Rx socket could be receiving the ARP messages (it is, indeed). Shortly put, Ip RAW sockets is how you create and send ICMPs and stuff like that. However, you need a special care when you receive through a RAW socket, because you'll receive almost everything.
It is possible, of course, to add filters to the RAW sockets, but (again) you need to know what to filter.

As a side note, in the code you posted the "port" is totally ignored when you use a RAW socket... you'd have to use a "protocol" instead, but to set it you need to use SetProtocol (or the corresponding attribute).
Funny enough, when you receive a packet, the protocol is stored in the port value of the InetSocketAddress. Weird but it's how it works.

Hope this helps,

T.

Matteo Danieletto

unread,
Aug 5, 2015, 2:41:38 PM8/5/15
to ns-3-users
Hi Tommaso,
thank you to reply me. 
Yes it was really helpful. Now I know where I can read something more.

There is a little question open: Why in ns3 when I use ns3::UdpSocketFactory the callback connected to Rx trace is never fired? 
I attach the code and you can just run without any input arguments.

I don't know if in your previous answer  there was implicit explanation of my question.

Thank you
Matteo
example4.cc

Tommaso Pecorella

unread,
Aug 5, 2015, 6:09:07 PM8/5/15
to ns-3-users
Hi Matteo,

the answer was only partially implicit. It was well hidden.
An InetSocketAddress usually stores an IP / port value. It is also used in IpRawSockets, and there the port is not used at all.
Now, there are two constructors for InetSocketAddress. One takes two arguments, the other just one. The second argument is the port, and guess what is the port number for an InetSocketAddress built with just one argument ? Zero, of course.

In your code...
  PacketSinkHelper receiver1 = PacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (interfaces.GetAddress (idSinkNode));
is initializing the receiver to listen to the port number zero. While the sender is sending to port 20 :)

The right line is
  PacketSinkHelper receiver1 = PacketSinkHelper ("ns3::UdpSocketFactory", InetSocketAddress (interfaces.GetAddress (idSinkNode), port);

Don't bash your head into the wall. It's like when you're searching for your glasses and they're on top of your head, or you're looking for the keys of the car, and you have them in your pocket.

Have fun,

T.

Matteo Danieletto

unread,
Aug 5, 2015, 6:23:45 PM8/5/15
to ns-3-users
Damn, you are right! 

Thank you Tommaso
Cheers
Matteo 
Reply all
Reply to author
Forward
0 new messages