Bugzilla – Bug 2555
Inet to Address conversion drops the TOS
Last modified: 2017-01-26 14:44:33 EST
The discussion is here: https://groups.google.com/forum/#!topic/ns-3-users/SSYjxAnQANM Basically the problem is that any conversion between an InetSocketAddress to Address will discard the Tos. This is not safe, and a lot of applications will loose silently the Tos in this way.
Forgive me, could you please point me to some of such lossy conversions?
(In reply to Stefano Avallone from comment #1) > Forgive me, could you please point me to some of such lossy conversions? In examples/traffic-control/traffic-control.cc there is this: AddressValue remoteAddress (InetSocketAddress (interfaces.GetAddress (0), port)); onoff.SetAttribute ("Remote", remoteAddress); apps.Add (onoff.Install (nodes.Get (1))); apps.Start (Seconds (1.0)); apps.Stop (Seconds (simulationTime + 0.1)); You can not set the TOS without adding one more parameter to the helper, because even if you add the proper TOS to InetSocketAddress (interfaces.GetAddress (0), port), it will be lost in the conversion to AddressValue (it's a constructor for real).
To my understanding, Address objects do not involve real conversions. They have a buffer which is simply carried around. What changed with the addition of the ToS field is that this buffer is 7 bytes long instead of 6. If "conversions" were a problem, then you would have issues with the IP address and port as well, since they are not defined in the Address base class. As a proof, I changed the code in traffic-control.cc to: InetSocketAddress rmt (interfaces.GetAddress (0), port); rmt.SetTos (0xb8); AddressValue remoteAddress (rmt); onoff.SetAttribute ("Remote", remoteAddress); apps.Add (onoff.Install (nodes.Get (1))); apps.Start (Seconds (1.0)); apps.Stop (Seconds (simulationTime + 0.1)); and used the (updated) patch in codereview 304500043 to show the DSCP of the packets: *** Flow monitor statistics *** Tx Packets: 7682 Tx Bytes: 11509900 Offered Load: 10.003 Mbps Rx Packets: 7641 Rx Bytes: 11448400 Packets Dropped by Queue Disc: 41 Bytes Dropped by Queue Disc: 61500 Packets Dropped by NetDevice: 0 Bytes Dropped by NetDevice: 0 Throughput: 9.94953 Mbps Mean delay: 0.0143646 Mean jitter: 0.00119161 DSCP value: 0x2e which shows that the TOS is correctly set.
You're right. Perhaps we should add an example. Closing this bug as invalid.
Hi Guys, sorry for late response! I'm new in NS3 developing groups and emails, so I cannot find codereview 304500043 which you mentioned. Stefano, can you please attach your testing script or point me a link to your testing script? I cannot get it work with your solution. Thanks, M
OK, I made it working but I would like to propose additional code to support both ways (old by using socket->SetIpTos and the latest by setting ToS via InetSocketAddress) of setting TOS values. Just to add one "if loop" before calling function SetIpTos in TcpSocketBase. This loop is used to check whether ToS is set to the address and add that ToS value if it is set. Otherwise, ToS value which was set by the socket->SetIpTos will remain and it will not be overwritten. What do you think? int TcpSocketBase::Bind (const Address &address) { NS_LOG_FUNCTION (this << address); if (InetSocketAddress::IsMatchingType (address)) { InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); Ipv4Address ipv4 = transport.GetIpv4 (); uint16_t port = transport.GetPort (); if( transport.GetTos () > 0) {//THIS LINE; Note that ToS is 0 by default SetIpTos (transport.GetTos ()); } and here int TcpSocketBase::Connect (const Address & address) { NS_LOG_FUNCTION (this << address); // If haven't do so, Bind() this socket first if (InetSocketAddress::IsMatchingType (address)) // && m_endPoint6 == 0 { if (m_endPoint == 0) { if (Bind () == -1) { NS_ASSERT (m_endPoint == 0); return -1; // Bind() failed } NS_ASSERT (m_endPoint != 0); } InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); m_endPoint->SetPeer (transport.GetIpv4 (), transport.GetPort ()); if( transport.GetTos () > 0){ //THIS LINE; Note that ToS is 0 by default SetIpTos (transport.GetTos ()); }
Created attachment 2711 [details] Patch for ToS supporting socket.SetIpTos and InetSocketAddress.SetTos My previous comment is related to TCP but it cannot work for UDP. Therefore, I provide patch for tcp-socket-base.cc and udp-socket-impl.cc in attachment. The patch is tested using traffic-control.cc.
Hi Miralem, I think you can get the old behavior by calling Socket::SetIpTos after invonking bind and connect. Correct?
(In reply to Stefano Avallone from comment #8) > Hi Miralem, > > I think you can get the old behavior by calling Socket::SetIpTos after > invonking bind and connect. Correct? Sure, but that will mean that Connect (TCP handshake) packets will be sent without TOS value, right?