From c8300ef811630ed7df88aad5f87dc2e6c4f831ff Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Thu, 14 Jul 2016 15:59:55 +0200 Subject: [PATCH] internet: Add a tos field to InetSockAddress --- src/internet/model/tcp-socket-base.cc | 6 ++-- src/internet/model/tcp-socket-base.h | 5 +++ src/internet/model/udp-socket-impl.cc | 21 +++++++----- src/internet/model/udp-socket-impl.h | 11 +++++- src/network/utils/inet-socket-address.cc | 43 ++++++++++++++++++------ src/network/utils/inet-socket-address.h | 9 +++++ 6 files changed, 73 insertions(+), 22 deletions(-) diff --git a/src/internet/model/tcp-socket-base.cc b/src/internet/model/tcp-socket-base.cc index 6c83bd757..ec8b4454e 100644 --- a/src/internet/model/tcp-socket-base.cc +++ b/src/internet/model/tcp-socket-base.cc @@ -549,6 +549,7 @@ TcpSocketBase::Bind (const Address &address) InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); Ipv4Address ipv4 = transport.GetIpv4 (); uint16_t port = transport.GetPort (); + SetIpTos (transport.GetTos ()); if (ipv4 == Ipv4Address::GetAny () && port == 0) { m_endPoint = m_tcp->Allocate (); @@ -661,6 +662,7 @@ TcpSocketBase::Connect (const Address & address) } InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); m_endPoint->SetPeer (transport.GetIpv4 (), transport.GetPort ()); + SetIpTos (transport.GetTos ()); m_endPoint6 = 0; // Get the appropriate local address and port number from the routing protocol and set up endpoint @@ -2135,7 +2137,7 @@ TcpSocketBase::SendEmptyPacket (uint8_t flags) * if both options are set. Once the packet got to layer three, only * the corresponding tags will be read. */ - if (IsManualIpTos ()) + if (GetIpTos ()) { SocketIpTosTag ipTosTag; ipTosTag.SetTos (GetIpTos ()); @@ -2439,7 +2441,7 @@ TcpSocketBase::SendDataPacket (SequenceNumber32 seq, uint32_t maxSize, bool with * if both options are set. Once the packet got to layer three, only * the corresponding tags will be read. */ - if (IsManualIpTos ()) + if (GetIpTos ()) { SocketIpTosTag ipTosTag; ipTosTag.SetTos (GetIpTos ()); diff --git a/src/internet/model/tcp-socket-base.h b/src/internet/model/tcp-socket-base.h index dd25f292c..42cb97121 100644 --- a/src/internet/model/tcp-socket-base.h +++ b/src/internet/model/tcp-socket-base.h @@ -198,6 +198,11 @@ public: * this class is modified from the original NS-3 TCP socket implementation * (TcpSocketImpl) by Raj Bhattacharjea of Georgia Tech. * + * For IPv4 packets, the TOS set for the socket is used. The Bind and Connect + * operations set the TOS for the socket to the value specified in the provided + * address. A SocketIpTos tag is only added to the packet if the resulting + * TOS is non-null. + * * Congestion state machine * --------------------------- * diff --git a/src/internet/model/udp-socket-impl.cc b/src/internet/model/udp-socket-impl.cc index d66ab27ed..3ff11c047 100644 --- a/src/internet/model/udp-socket-impl.cc +++ b/src/internet/model/udp-socket-impl.cc @@ -256,6 +256,7 @@ UdpSocketImpl::Bind (const Address &address) InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); Ipv4Address ipv4 = transport.GetIpv4 (); uint16_t port = transport.GetPort (); + SetIpTos (transport.GetTos ()); if (ipv4 == Ipv4Address::GetAny () && port == 0) { m_endPoint = m_udp->Allocate (); @@ -374,6 +375,7 @@ UdpSocketImpl::Connect (const Address & address) InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); m_defaultAddress = Address(transport.GetIpv4 ()); m_defaultPort = transport.GetPort (); + SetIpTos (transport.GetTos ()); m_connected = true; NotifyConnectionSucceeded (); } @@ -445,7 +447,7 @@ UdpSocketImpl::DoSend (Ptr p) if (Ipv4Address::IsMatchingType (m_defaultAddress)) { - return DoSendTo (p, Ipv4Address::ConvertFrom (m_defaultAddress), m_defaultPort); + return DoSendTo (p, Ipv4Address::ConvertFrom (m_defaultAddress), m_defaultPort, GetIpTos ()); } else if (Ipv6Address::IsMatchingType (m_defaultAddress)) { @@ -457,9 +459,9 @@ UdpSocketImpl::DoSend (Ptr p) } int -UdpSocketImpl::DoSendTo (Ptr p, Ipv4Address dest, uint16_t port) +UdpSocketImpl::DoSendTo (Ptr p, Ipv4Address dest, uint16_t port, uint8_t tos) { - NS_LOG_FUNCTION (this << p << dest << port); + NS_LOG_FUNCTION (this << p << dest << port << tos); if (m_boundnetdevice) { NS_LOG_LOGIC ("Bound interface number " << m_boundnetdevice->GetIfIndex ()); @@ -485,10 +487,10 @@ UdpSocketImpl::DoSendTo (Ptr p, Ipv4Address dest, uint16_t port) return -1; } - if (IsManualIpTos ()) + if (tos) { SocketIpTosTag ipTosTag; - ipTosTag.SetTos (GetIpTos ()); + ipTosTag.SetTos (tos); // This packet may already have a SocketIpTosTag (see BUG 2440) p->ReplacePacketTag (ipTosTag); } @@ -654,7 +656,7 @@ UdpSocketImpl::DoSendTo (Ptr p, Ipv6Address dest, uint16_t port) if (dest.IsIpv4MappedAddress ()) { - return (DoSendTo(p, dest.GetIpv4MappedAddress (), port)); + return (DoSendTo(p, dest.GetIpv4MappedAddress (), port, 0)); } if (m_boundnetdevice) { @@ -783,7 +785,8 @@ UdpSocketImpl::SendTo (Ptr p, uint32_t flags, const Address &address) InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); Ipv4Address ipv4 = transport.GetIpv4 (); uint16_t port = transport.GetPort (); - return DoSendTo (p, ipv4, port); + uint8_t tos = transport.GetTos (); + return DoSendTo (p, ipv4, port, tos); } else if (Inet6SocketAddress::IsMatchingType (address)) { @@ -875,7 +878,9 @@ UdpSocketImpl::GetPeerName (Address &address) const if (Ipv4Address::IsMatchingType (m_defaultAddress)) { Ipv4Address addr = Ipv4Address::ConvertFrom (m_defaultAddress); - address = InetSocketAddress (addr, m_defaultPort); + InetSocketAddress inet (addr, m_defaultPort); + inet.SetTos (GetIpTos ()); + address = inet; } else if (Ipv6Address::IsMatchingType (m_defaultAddress)) { diff --git a/src/internet/model/udp-socket-impl.h b/src/internet/model/udp-socket-impl.h index 6688b6d56..6773226e2 100644 --- a/src/internet/model/udp-socket-impl.h +++ b/src/internet/model/udp-socket-impl.h @@ -49,6 +49,14 @@ class Ipv6Interface; * * This class subclasses ns3::UdpSocket, and provides a socket interface * to ns3's implementation of UDP. + * + * For IPv4 packets, the TOS is set according to the following rules: + * - if the socket is connected, the TOS set for the socket is used + * - if the socket is not connected, the TOS specified in the destination address + * passed to SendTo is used, while the TOS set for the socket is ignored + * In both cases, a SocketIpTos tag is only added to the packet if the resulting + * TOS is non-null. The Bind and Connect operations set the TOS for the + * socket to the value specified in the provided address. */ class UdpSocketImpl : public UdpSocket @@ -178,9 +186,10 @@ private: * \param p packet * \param daddr destination address * \param dport destination port + * \param tos ToS * \returns 0 on success, -1 on failure */ - int DoSendTo (Ptr p, Ipv4Address daddr, uint16_t dport); + int DoSendTo (Ptr p, Ipv4Address daddr, uint16_t dport, uint8_t tos); /** * \brief Send a packet to a specific destination and port (IPv6) * \param p packet diff --git a/src/network/utils/inet-socket-address.cc b/src/network/utils/inet-socket-address.cc index f678c455a..2139eca75 100644 --- a/src/network/utils/inet-socket-address.cc +++ b/src/network/utils/inet-socket-address.cc @@ -28,31 +28,36 @@ NS_LOG_COMPONENT_DEFINE ("InetSocketAddress"); InetSocketAddress::InetSocketAddress (Ipv4Address ipv4, uint16_t port) : m_ipv4 (ipv4), - m_port (port) + m_port (port), + m_tos (0) { NS_LOG_FUNCTION (this << ipv4 << port); } InetSocketAddress::InetSocketAddress (Ipv4Address ipv4) : m_ipv4 (ipv4), - m_port (0) + m_port (0), + m_tos (0) { NS_LOG_FUNCTION (this << ipv4); } InetSocketAddress::InetSocketAddress (const char *ipv4, uint16_t port) : m_ipv4 (Ipv4Address (ipv4)), - m_port (port) + m_port (port), + m_tos (0) { NS_LOG_FUNCTION (this << ipv4 << port); } InetSocketAddress::InetSocketAddress (const char * ipv4) : m_ipv4 (Ipv4Address (ipv4)), - m_port (0) + m_port (0), + m_tos (0) { NS_LOG_FUNCTION (this << ipv4); } InetSocketAddress::InetSocketAddress (uint16_t port) : m_ipv4 (Ipv4Address::GetAny ()), - m_port (port) + m_port (port), + m_tos (0) { NS_LOG_FUNCTION (this << port); } @@ -68,6 +73,12 @@ InetSocketAddress::GetIpv4 (void) const NS_LOG_FUNCTION (this); return m_ipv4; } +uint8_t +InetSocketAddress::GetTos (void) const +{ + NS_LOG_FUNCTION (this); + return m_tos; +} void InetSocketAddress::SetPort (uint16_t port) @@ -81,12 +92,18 @@ InetSocketAddress::SetIpv4 (Ipv4Address address) NS_LOG_FUNCTION (this << address); m_ipv4 = address; } +void +InetSocketAddress::SetTos (uint8_t tos) +{ + NS_LOG_FUNCTION (this << tos); + m_tos = tos; +} bool InetSocketAddress::IsMatchingType (const Address &address) { NS_LOG_FUNCTION (&address); - return address.CheckCompatible (GetType (), 6); + return address.CheckCompatible (GetType (), 7); } InetSocketAddress::operator Address () const @@ -98,22 +115,26 @@ Address InetSocketAddress::ConvertTo (void) const { NS_LOG_FUNCTION (this); - uint8_t buf[6]; + uint8_t buf[7]; m_ipv4.Serialize (buf); buf[4] = m_port & 0xff; buf[5] = (m_port >> 8) & 0xff; - return Address (GetType (), buf, 6); + buf[6] = m_tos; + return Address (GetType (), buf, 7); } InetSocketAddress InetSocketAddress::ConvertFrom (const Address &address) { NS_LOG_FUNCTION (&address); - NS_ASSERT (address.CheckCompatible (GetType (), 6)); - uint8_t buf[6]; + NS_ASSERT (address.CheckCompatible (GetType (), 7)); + uint8_t buf[7]; address.CopyTo (buf); Ipv4Address ipv4 = Ipv4Address::Deserialize (buf); uint16_t port = buf[4] | (buf[5] << 8); - return InetSocketAddress (ipv4, port); + uint8_t tos = buf[6]; + InetSocketAddress inet (ipv4, port); + inet.SetTos (tos); + return inet; } uint8_t InetSocketAddress::GetType (void) diff --git a/src/network/utils/inet-socket-address.h b/src/network/utils/inet-socket-address.h index 2add09952..218b5ec81 100644 --- a/src/network/utils/inet-socket-address.h +++ b/src/network/utils/inet-socket-address.h @@ -76,6 +76,10 @@ public: * \returns the ipv4 address */ Ipv4Address GetIpv4 (void) const; + /** + * \returns the ToS + */ + uint8_t GetTos (void) const; /** * \param port the new port number. @@ -85,6 +89,10 @@ public: * \param address the new ipv4 address */ void SetIpv4 (Ipv4Address address); + /** + * \param tos the new ToS. + */ + void SetTos (uint8_t tos); /** * \param address address to test @@ -120,6 +128,7 @@ private: static uint8_t GetType (void); Ipv4Address m_ipv4; //!< the IPv4 address uint16_t m_port; //!< the port + uint8_t m_tos; //!< the ToS }; } // namespace ns3