Implement IPTTL socket option for UDP

This commit is contained in:
Tom Henderson
2008-05-17 11:15:02 -07:00
parent 0a476b4f04
commit 67d54a7f8a
5 changed files with 122 additions and 19 deletions

View File

@@ -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> 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<Ipv4Interface> outInterface = *ifaceIter;
if (destination.IsSubnetDirectedBroadcast (
outInterface->GetNetworkMask ()))
{
ipHeader.SetTtl (1);
}
}
}
if (destination.IsBroadcast ())
{
uint32_t ifaceIndex = 0;

View File

@@ -52,24 +52,14 @@ UdpSocket::GetTypeId (void)
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 @@ 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<Packet> 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<Packet> p, Ipv4Address dest, uint16_t port)
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

View File

@@ -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;

View File

@@ -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> ("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

View File

@@ -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 */