Implement IPTTL socket option for UDP
authorTom Henderson <tomh@tomh.org>
Sat, 17 May 2008 11:15:02 -0700
changeset 3124 473e59b5e141
parent 3123 fae57a467d54
child 3125 d2d8a36cfd23
Implement IPTTL socket option for UDP
src/internet-node/ipv4-l3-protocol.cc
src/internet-node/udp-socket.cc
src/internet-node/udp-socket.h
src/node/socket.cc
src/node/socket.h
--- a/src/internet-node/ipv4-l3-protocol.cc	Fri May 16 21:28:07 2008 -0700
+++ b/src/internet-node/ipv4-l3-protocol.cc	Sat May 17 11:15:02 2008 -0700
@@ -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 @@
 
   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<Ipv4Interface> outInterface = *ifaceIter;
+          if (destination.IsSubnetDirectedBroadcast (
+                outInterface->GetNetworkMask ()))
+          {
+            ipHeader.SetTtl (1);
+          }
+        }
+    }
   if (destination.IsBroadcast ())
     {
       uint32_t ifaceIndex = 0;
--- a/src/internet-node/udp-socket.cc	Fri May 16 21:28:07 2008 -0700
+++ b/src/internet-node/udp-socket.cc	Sat May 17 11:15:02 2008 -0700
@@ -52,24 +52,14 @@
                    UintegerValue (0xffffffffl),
                    MakeUintegerAccessor (&UdpSocket::m_rcvBufSize),
                    MakeUintegerChecker<uint32_t> ())
-    .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<uint8_t> ())
     .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<uint8_t> ())
     ;
@@ -232,7 +222,6 @@
 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 @@
 {
   NS_LOG_FUNCTION (this << p << dest << port);
 
-  Ipv4Route routeToDest;
-
   if (m_endPoint == 0)
     {
       if (Bind () == -1)
@@ -329,6 +316,26 @@
   uint32_t localIfIndex;
   Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
 
+  // 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
--- a/src/internet-node/udp-socket.h	Fri May 16 21:28:07 2008 -0700
+++ b/src/internet-node/udp-socket.h	Sat May 17 11:15:02 2008 -0700
@@ -92,8 +92,6 @@
   
   // Socket options (UdpSocket attributes)
   uint32_t m_rcvBufSize;
-  bool m_dontRoute;
-  bool m_acceptConn;
   uint8_t m_ipTtl;
   uint8_t m_ipMulticastTtl;
 
--- a/src/node/socket.cc	Fri May 16 21:28:07 2008 -0700
+++ b/src/node/socket.cc	Sat May 17 11:15:02 2008 -0700
@@ -301,4 +301,52 @@
   return m_address;
 }
 
+SocketIpTtlTag::SocketIpTtlTag ()  
+{
+}
+
+uint32_t 
+SocketIpTtlTag::GetUid (void)
+{
+  static uint32_t uid = ns3::Tag::AllocateUid<SocketIpTtlTag> ("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
--- a/src/node/socket.h	Fri May 16 21:28:07 2008 -0700
+++ b/src/node/socket.h	Sat May 17 11:15:02 2008 -0700
@@ -378,6 +378,26 @@
   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 */