diff --git a/src/internet-node/ipv4-l3-protocol.cc b/src/internet-node/ipv4-l3-protocol.cc index 9188a358e..7be8959c9 100644 --- a/src/internet-node/ipv4-l3-protocol.cc +++ b/src/internet-node/ipv4-l3-protocol.cc @@ -24,6 +24,7 @@ #include "ns3/ipv4-address.h" #include "ns3/ipv4-route.h" #include "ns3/node.h" +#include "ns3/socket.h" #include "ns3/net-device.h" #include "ns3/uinteger.h" #include "ns3/trace-source-accessor.h" @@ -486,6 +487,35 @@ Ipv4L3Protocol::Send (Ptr packet, m_identification ++; + // Set TTL to 1 if it is a broadcast packet of any type. Otherwise, + // possibly override the default TTL if the packet is tagged + SocketIpTtlTag tag; + bool found = packet->PeekTag (tag); + uint8_t socketTtl = tag.GetTtl (); + packet->RemoveTag (tag); + + if (destination.IsBroadcast ()) + { + ipHeader.SetTtl (1); + } + else if (found) + { + ipHeader.SetTtl (socketTtl); + } + else + { + uint32_t ifaceIndex = 0; + for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin (); + ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++) + { + Ptr outInterface = *ifaceIter; + if (destination.IsSubnetDirectedBroadcast ( + outInterface->GetNetworkMask ())) + { + ipHeader.SetTtl (1); + } + } + } if (destination.IsBroadcast ()) { uint32_t ifaceIndex = 0; diff --git a/src/internet-node/udp-socket.cc b/src/internet-node/udp-socket.cc index 2f6e232b6..d2689dfbb 100644 --- a/src/internet-node/udp-socket.cc +++ b/src/internet-node/udp-socket.cc @@ -52,24 +52,14 @@ UdpSocket::GetTypeId (void) UintegerValue (0xffffffffl), MakeUintegerAccessor (&UdpSocket::m_rcvBufSize), MakeUintegerChecker ()) - .AddAttribute ("DontRoute", - "Bypass normal routing; destination must be local", - BooleanValue (false), - MakeBooleanAccessor (&UdpSocket::m_dontRoute), - MakeBooleanChecker ()) - .AddAttribute ("AcceptConn", - "Whether a socket is enabled for listening (read-only)", - BooleanValue (false), - MakeBooleanAccessor (&UdpSocket::m_acceptConn), - MakeBooleanChecker ()) .AddAttribute ("IpTtl", - "Time-to-live for unicast IP packets", - UintegerValue (64), + "socket-specific TTL for unicast IP packets (if non-zero)", + UintegerValue (0), MakeUintegerAccessor (&UdpSocket::m_ipTtl), MakeUintegerChecker ()) .AddAttribute ("IpMulticastTtl", - "Time-to-live for multicast IP packets", - UintegerValue (64), + "socket-specific TTL for multicast IP packets (if non-zero)", + UintegerValue (0), MakeUintegerAccessor (&UdpSocket::m_ipMulticastTtl), MakeUintegerChecker ()) ; @@ -232,7 +222,6 @@ int UdpSocket::Connect(const Address & address) { NS_LOG_FUNCTION (this << address); - Ipv4Route routeToDest; InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); m_defaultAddress = transport.GetIpv4 (); m_defaultPort = transport.GetPort (); @@ -303,8 +292,6 @@ UdpSocket::DoSendTo (Ptr p, Ipv4Address dest, uint16_t port) { NS_LOG_FUNCTION (this << p << dest << port); - Ipv4Route routeToDest; - if (m_endPoint == 0) { if (Bind () == -1) @@ -329,6 +316,26 @@ UdpSocket::DoSendTo (Ptr p, Ipv4Address dest, uint16_t port) uint32_t localIfIndex; Ptr ipv4 = m_node->GetObject (); + // Locally override the IP TTL for this socket + // We cannot directly modify the TTL at this stage, so we set a Packet tag + // The destination can be either multicast, unicast/anycast, or + // either all-hosts broadcast or limited (subnet-directed) broadcast. + // For the latter two broadcast types, the TTL will later be set to one + // irrespective of what is set in these socket options. So, this tagging + // may end up setting the TTL of a limited broadcast packet to be + // the same as a unicast, but it will be fixed further down the stack + if (m_ipMulticastTtl != 0 && dest.IsMulticast ()) + { + SocketIpTtlTag tag; + tag.SetTtl (m_ipMulticastTtl); + p->AddTag (tag); + } + else if (m_ipTtl != 0 && !dest.IsMulticast () && !dest.IsBroadcast ()) + { + SocketIpTtlTag tag; + tag.SetTtl (m_ipTtl); + p->AddTag (tag); + } // // If dest is sent to the limited broadcast address (all ones), // convert it to send a copy of the packet out of every interface diff --git a/src/internet-node/udp-socket.h b/src/internet-node/udp-socket.h index be545a02a..812d5f552 100644 --- a/src/internet-node/udp-socket.h +++ b/src/internet-node/udp-socket.h @@ -92,8 +92,6 @@ private: // Socket options (UdpSocket attributes) uint32_t m_rcvBufSize; - bool m_dontRoute; - bool m_acceptConn; uint8_t m_ipTtl; uint8_t m_ipMulticastTtl; diff --git a/src/node/socket.cc b/src/node/socket.cc index f00625885..8b066edd7 100644 --- a/src/node/socket.cc +++ b/src/node/socket.cc @@ -301,4 +301,52 @@ SocketRxAddressTag::GetAddress (void) const return m_address; } +SocketIpTtlTag::SocketIpTtlTag () +{ +} + +uint32_t +SocketIpTtlTag::GetUid (void) +{ + static uint32_t uid = ns3::Tag::AllocateUid ("SocketIpTtlTag.ns3"); + return uid; +} + +void +SocketIpTtlTag::Print (std::ostream &os) const +{ + os << "ttl="<< m_ttl; +} + +uint32_t +SocketIpTtlTag::GetSerializedSize (void) const +{ + return 0; +} + +void +SocketIpTtlTag::Serialize (Buffer::Iterator i) const +{ + // for local use in stack only +} + +uint32_t +SocketIpTtlTag::Deserialize (Buffer::Iterator i) +{ + // for local use in stack only + return 0; +} + +void +SocketIpTtlTag::SetTtl (uint8_t ttl) +{ + m_ttl = ttl; +} + +uint8_t +SocketIpTtlTag::GetTtl (void) const +{ + return m_ttl; +} + }//namespace ns3 diff --git a/src/node/socket.h b/src/node/socket.h index 847113e84..1ea91aebc 100644 --- a/src/node/socket.h +++ b/src/node/socket.h @@ -378,6 +378,26 @@ private: Address m_address; }; +/** + * \brief This class implements a tag that carries the socket-specific + * TTL of a packet to the IP layer + */ +class SocketIpTtlTag : public Tag +{ +public: + SocketIpTtlTag (); + static uint32_t GetUid (void); + void Print (std::ostream &os) const; + uint32_t GetSerializedSize (void) const; + void Serialize (Buffer::Iterator i) const; + uint32_t Deserialize (Buffer::Iterator i); + + void SetTtl (uint8_t ttl); + uint8_t GetTtl (void) const; +private: + uint8_t m_ttl; +}; + } //namespace ns3 #endif /* SOCKET_H */