Sarajevo, Bosnia and Herzegovina

IP ToS fields with UDPSockets – implementation issue

download

For the purposes of my project, I needed to add TOS tag to UDP packets which are generated by OLSR routing protocol. In olsr-routing-protocol.cc I added ToS Values:
// Create a socket to listen only on this interface
      Ptr socket = Socket::CreateSocket (GetObject (),UdpSocketFactory::GetTypeId ());
      socket->SetAllowBroadcast (true); 
      socket->SetIpTos(6);   
      socket->SetIpRecvTos(true);

And when I executed the code I received the following error:

‘build’ finished successfully (1m21.071s)
assert failed. cond=”cur->tid != tag.GetInstanceTypeId ()”, file=../src/network/model/packet-tag-list.cc, line=250
terminate called without an active exception
Command [‘/home/mickey/ns3_git/ns-allinone-3.22/ns-3.22/build/scratch/my_channel_test’] terminated with signal SIGIOT. Run it under a debugger to get more information (./waf –run <program> –command-template=”gdb –args %s <args>”).

When I dig up more into the code, I found the problem which was that the OLSR sometimes generate the packet and in case that there is no valid route to the destination it will send the packet to the local interface (loopback function) which will return the packet once again to OLSR. This is done with intent since OLSR is hoping that it might find the valid route very soon to send that packet to the network. However, OLSR all the time is sending this packet down to the lower network layer and UdpSocketList is trying each time to write the ToS value to  IP packet. Since ToS value already exists (packet was already marked once), there is an upper shown error in packet-tag-list.cc
The simple solution is to check if there is ANY of ToS value in the packet, and if there is no tag, UdpSocketImpl should write it.
So every time UdpSocketImpl wants to add new tag it should check whether there is any tag already written. If the tag already exist it should either remove it and write the new tag or just discard any change. However, that discussion is out-of-scope of this post.In /src/internet/model/udp-socket-impl.cc in function
int UdpSocketImpl::DoSendTo (Ptr<Packet> p, Ipv4Address dest, uint16_t port) {…
add the following line before very AddPacketTag (ipTosTag) like:
if (IsManualIpTos ())
    {
      SocketIpTosTag ipTosTag;
      ipTosTag.SetTos (GetIpTos ());
      if(p->PeekPacketTag(ipTosTag) == false) //this line is necessary
      p->AddPacketTag (ipTosTag);
    }
I believe it should be done for all other tags, like TTL and etc.
M